jeudi 22 octobre 2020

Laravel: Best approach to store logic for calculate and determine model mutators

I have 2 models, one of them(Product) depends on other(User). Product model has 4 prices' fields.

Product:
price_level_0  //100
price_level_1  //90
price_level_2   //80
price_level_3   //70

User model has a method to calculate the user's discount.

User->getDiscountLevel()

 then we can get discount's level by 

$user->discount_level //2

Depending on the user discount's level we have to get 3 fields from the Product model.  

price //80
oldPrice //90
isMaxLevelDiscount= true/false

ProductController

public function index(Request $request)
{
    $user = Auth::user();
    $user->determineDiscountLevel();

    $list=Product::offset($offset)->limit($limit)->get();
    $products=$list->map(function (Product $item) use ($user) {
        $item->setPrices($user);
    });

    $listSimilar=Product::similar()->get();
    $productsSimilar=$listSimilar->map(function (Product $item) use ($user) {
        $item->setPrices($user);
    });

    return view('product.index')
        ->with('products', $products)
        ->with('productsSimilar', $productsSimilar);
}

public function Wishlist(Request $request)
{
    $user = Auth::user();
    $user->determineDiscountLevel();

    $wishlistProducts=Product::similar()->get();
    $wishlist=$wishlistProducts->map(function (Product $item) use ($user) {
        $item->setPrices($user);
    });

    return view('product.wishlist')
        ->with('wishlist', $wishlist);
}

Product model

public function setPrices(?User $user): void
{
    //Define mutators and values for them
    $this->attributes['price']=$this->price_level_0;
    $this->attributes['oldPrice ']=$this->price_level_0;
    $this->attributes['isMaxLevelDiscount']=false;

    if ($user) {
        $this->attributes['price']=$this['price_level_' . $user->discount_level];
        $prevLevel=$user->discount_level > 0 ? $user->discount_level-- : 0;
        $this->attributes['oldPrice']=$this['price_level_' . $prevLevel];
        $this->attributes['isMaxLevelDiscount']=$user->discount_level > 2 ? true : false;
    }
}

  I would like to avoid mapping and call set method $item->setPrices($user) to define mutators each time when I work with a Product model.

   $list->map(function (Product $item) use ($user) {
        $item->setPrices($user);
    });

What is the best approach for this? Create additional layer such as Repository or Service pattern where put the logic to work with the model and call product->setPrice() everytyme when read data?

In this case to get data we need to call through service like

$this->service->all($user);
$this->service->similar($user);
$this->service->wishlist($user);

Aucun commentaire:

Enregistrer un commentaire