Скидки на всю продукцию относятся к категории? - PullRequest
2 голосов
/ 10 февраля 2020

У меня есть эти таблицы:

products
-- name
-- price
-- quantity
-- category_id

discounts
-- type('percentage','numeric')
-- value
-- expired_at

categories 
-- name

discountables
-- discount_id
-- discountable_id
-- discountable_type

В discountables существует множество отношений между многими:

discounts and categories также discounts and products

Я закончил с тем, как сделать скидку между discounts and products

Теперь я запутался, Как сделать скидку на все товары, которые принадлежат категории, которую я добавляю к discountables

Отношение:

Категория Модели

public function discounts()
{
    return $this->morphToMany('App\Models\Discount', 'discountable');
}

Модели продуктов

public function discounts()
{
    return $this->morphToMany('App\Models\Discount', 'discountable');
}

Модель со скидкой:

public function categories()
{
    return $this->morphedByMany('App\Models\Category', 'discountable')->withTimestamps();
}

public function products()
{
    return $this->morphedByMany('App\Models\Product', 'discountable')->withTimestamps();
}

Мой код для скидки непосредственно на продукты discounts and products

  /**
 * get price of product after discount
 *
 * @return void
 */
public function getDiscountProductAttribute() {
    foreach ($this->discounts as $discount) {
        if($discount->expired_at > Carbon::now()){
            if ($discount->type == 'numeric'){
                return $this->price - $discount->value;
            }else{
                return $this->price - ($this->price * ($discount->value / 100));
            }
        }
    }
}

Так что мне нужно Как сделать скидку на весь товар, который принадлежит категории, которую я добавляю к discountables?

1 Ответ

1 голос
/ 11 февраля 2020

Ваши отношения в порядке. Я просто немного изменил дизайн, чтобы решить эту проблему.

class Discount extends Model
{
    /**
    * Check whether this discount is expired.
    *
    * return bool
    */
    public function expired()
    {
        // I assume that expired_at is also a Carbon instance.
        return $this->expired_at->isPast();
    }

    /**
    * Return the discount amount for each product.
    *
    * @return double
    */
    public function apply(Product $product)
    {
        if ($this->type === 'numeric') {
            $this->value;
        }

        if ($this->type === 'percentage') {
            return $product->price * ($this->value / 100);
        }

        return 0;
    }
}
class Product extends Model
{
    public function allDiscounts()
    {
        return $this->discounts
            ->merge($this->category->discounts)
            ->unique();
    }

    pubic function getTotalDiscountAttribute()
    {
        return $this->allDiscounts()
            ->reject
            ->expired()
            ->map
            ->apply($this)
            ->sum();
    }

    public function getTotalPriceAttribute()
    {
         return $this->price - $this->total_discount;
    }
}

Таким образом, вы можете получить полную цену за один продукт, применив все виды скидок от себя и его категории (если есть) по просто говоря:

$product->total_price;

Надеюсь, это поможет. Дайте мне знать, если он потерпит неудачу на каком-либо этапе.

Кстати. Ваш вопрос напоминает мне о довольно хорошей речи несколько лет назад. Речь идет о решении некоторых схожих проблем с использованием наследования и Null Object Pattern. Это довольно круто. Вам не нужно переписывать это таким образом, но это довольно хороший дизайн.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...