240 lines
6.6 KiB
PHP
240 lines
6.6 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Enums\DiscountType;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Illuminate\Support\Str;
|
|
use Kwaadpepper\Enum\Traits\CastsEnums;
|
|
|
|
class Discount extends Model
|
|
{
|
|
use CastsEnums;
|
|
use HasFactory;
|
|
|
|
/**
|
|
* The attributes that should be cast to native types.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $casts = [
|
|
'status' => 'bool',
|
|
'date_start' => 'datetime',
|
|
'date_end' => 'datetime',
|
|
];
|
|
|
|
/**
|
|
* The attributes that should be cast to Enums.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $enumCasts = [
|
|
'type' => DiscountType::class,
|
|
];
|
|
|
|
/**
|
|
* The attributes that are mass assignable.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $fillable = [
|
|
'type', 'discount_value',
|
|
'status', 'date_start', 'date_end',
|
|
];
|
|
|
|
/**
|
|
* Perform any actions required after the model boots.
|
|
*
|
|
* @return void
|
|
*/
|
|
protected static function booted()
|
|
{
|
|
// * EVENT CLOSURES.
|
|
static::creating(function (self $model) {
|
|
// * ASSERTIONS
|
|
self::assertIsAboveZero(
|
|
'discount_value',
|
|
trans('Valeur de réduction'),
|
|
$model->getAttributeFromArray('discount_value')
|
|
);
|
|
// * TRANSFORMATIONS
|
|
$model->makeStatusSense();
|
|
});
|
|
static::created(function (self $model) {
|
|
$model->flashMessages();
|
|
});
|
|
static::updated(function (self $model) {
|
|
$model->flashMessages();
|
|
});
|
|
static::updating(function (self $model) {
|
|
// * ASSERTIONS
|
|
self::assertIsAboveZero(
|
|
'discount_value',
|
|
trans('Valeur de réduction'),
|
|
$model->getAttributeFromArray('discount_value')
|
|
);
|
|
// * TRANSFORMATIONS
|
|
$model->makeStatusSense();
|
|
});
|
|
}
|
|
|
|
// * RELATIONSHIPS
|
|
|
|
/**
|
|
* BelongsToMany products relation
|
|
*
|
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
|
*/
|
|
public function products()
|
|
{
|
|
return $this->belongsToMany(Product::class, 'product_discount');
|
|
}
|
|
|
|
// * METHODS
|
|
|
|
/**
|
|
* Flash boolean attributes modification messages
|
|
*
|
|
* @param boolean $old Ignore old attribute comparison.
|
|
* @return void
|
|
*/
|
|
public function flashMessages(bool $old = true)
|
|
{
|
|
$booleanChecks = [
|
|
'status' => [
|
|
'info' => trans(':model est maintenant pris en compte', [
|
|
'model' => Str::singular(trans('models.classes.discounts'))
|
|
]),
|
|
'warning' => trans(':model n\'est maintenant plus pris en compte', [
|
|
'model' => Str::singular(trans('models.classes.discounts'))
|
|
])
|
|
],
|
|
];
|
|
$sessionMessages = [];
|
|
|
|
// * Merge messages
|
|
foreach ($booleanChecks as $attribute => $booleanCheck) {
|
|
if ($old and $this->getOriginal($attribute) == $this->{$attribute}) {
|
|
continue;
|
|
}
|
|
/** @var string $flashType */
|
|
$flashType = \array_keys($booleanCheck)[$this->{$attribute} ? 0 : 1];
|
|
if (!\array_key_exists($flashType, $sessionMessages)) {
|
|
$sessionMessages[$flashType] = [];
|
|
}
|
|
$sessionMessages[$flashType][] = $booleanCheck[$flashType];
|
|
}
|
|
|
|
foreach ($sessionMessages as $flashType => $messages) {
|
|
session()->flash($flashType, collect($messages)->implode("\n"));
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Getter displayable_discount_value
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getDisplayableDiscountValueAttribute(): string
|
|
{
|
|
return $this->type->equals(\App\Enums\DiscountType::amount()) ?
|
|
number_format($this->discount_value, 2, ',', '') . ' €' :
|
|
number_format($this->discount_value, 0) . ' %';
|
|
}
|
|
|
|
/**
|
|
* Getter discount_value
|
|
*
|
|
* @return float
|
|
*/
|
|
public function getDiscountValueAttribute(): float
|
|
{
|
|
return $this->type->equals(\App\Enums\DiscountType::amount()) ?
|
|
\round(\floatval($this->attributes['discount_value']) / 100, 3) :
|
|
\floatval($this->attributes['discount_value']);
|
|
}
|
|
|
|
/**
|
|
* Setter discount_value
|
|
*
|
|
* @param float $value
|
|
* @return void
|
|
*/
|
|
public function setDiscountValueAttribute(float $value): void
|
|
{
|
|
$this->attributes['discount_value'] =
|
|
$this->type->equals(\App\Enums\DiscountType::amount()) ?
|
|
\intval(\ceil(\round($value * 100, 3))) :
|
|
\intval($value);
|
|
}
|
|
|
|
/**
|
|
* Assert Is Above Zero
|
|
*
|
|
* @param string $attribute
|
|
* @param string $name
|
|
* @param float $value
|
|
* @return void
|
|
* @throws \Illuminate\Validation\ValidationException If the value is less or equals to 0.
|
|
*/
|
|
private static function assertIsAboveZero(string $attribute, string $name, float $value): void
|
|
{
|
|
Validator::make([
|
|
$attribute => $value
|
|
], [
|
|
$attribute => 'numeric|min:0'
|
|
], [], [
|
|
$attribute => $name
|
|
])->validate();
|
|
}
|
|
|
|
/**
|
|
* Adjusts model status using current status and start and end dates
|
|
*
|
|
* @return void
|
|
*/
|
|
public function makeStatusSense(): void
|
|
{
|
|
/** @var \Carbon\Carbon|null */
|
|
$date_start = $this->date_start;
|
|
/** @var \Carbon\Carbon|null */
|
|
$date_end = $this->date_end;
|
|
// * Ignore unpublish_at in the past
|
|
if ($date_end and $date_end->lessThan(now())) {
|
|
return;
|
|
}
|
|
// * Ignore publish_at in the futur
|
|
if ($date_start and $date_start->greaterThan(now())) {
|
|
return;
|
|
}
|
|
if ($date_start or $date_end) {
|
|
$this->status = $this->planificated_status;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter the current status following planification dates
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function getPlanificatedStatusAttribute(): bool
|
|
{
|
|
/** @var \Carbon\Carbon|null */
|
|
$date_start = $this->date_start;
|
|
/** @var \Carbon\Carbon|null */
|
|
$date_end = $this->date_end;
|
|
if ($date_start and $date_end) {
|
|
return $date_end->greaterThanOrEqualTo(now()) and $date_start->lessThan(now());
|
|
}
|
|
if ($date_start) {
|
|
return $date_start->lessThan(now());
|
|
}
|
|
if ($date_end) {
|
|
return $date_end->greaterThanOrEqualTo(now());
|
|
}
|
|
return false;
|
|
}
|
|
}
|