Duplication of code in Laravel ORM

1

I was working and I came across the following situation:

if (($entrada == null) and ($parcela == null)) {
    $cotas = Produto::orderBy('credito', 'DESC')
        ->where('id_subcategoria', $subcategoria)
        ->where('visivel_site', self::SIM)
        ->where('credito', '<=', Utils::calculaPorcentagem($porcentagem, $credito))
        ->get();
} elseif ($parcela == null) {
    $cotas = Produto::orderBy('credito', 'DESC')
        ->where('id_subcategoria', $subcategoria)
        ->where('visivel_site', self::SIM)
        ->where('credito', '<=', Utils::calculaPorcentagem($porcentagem, $credito))
        ->where('entrada', '<=', Utils::calculaPorcentagem($porcentagem, $entrada))
        ->get();
} elseif ($entrada == null) {
    $cotas = Produto::orderBy('credito', 'DESC')
        ->where('id_subcategoria', $subcategoria)
        ->where('visivel_site', self::SIM)
        ->where('credito', '<=', Utils::calculaPorcentagem($porcentagem, $credito))
        ->whereHas('saldo', function ($query) use ($parcela, $porcentagem) {
            $query->where('parcela', '<=', Utils::calculaPorcentagem($porcentagem, $parcela));
        })
        ->get();
} else {
    $cotas = Produto::orderBy('credito', 'DESC')
        ->where('id_subcategoria', $subcategoria)
        ->where('visivel_site', self::SIM)
        ->where('credito', '<=', Utils::calculaPorcentagem($porcentagem, $credito))
        ->where('entrada', '<=', Utils::calculaPorcentagem($porcentagem, $entrada))
        ->whereHas('saldo', function ($query) use ($parcela, $porcentagem) {
            $query->where('parcela', '<=', Utils::calculaPorcentagem($porcentagem, $parcela));
        })
        ->get();
}

return $cotas;

Is there a more elegant way to create this function? That I did not repeat the code so much, I thought I would use pure SQL and go concatenating the instructions, it would be a better implementation ... remembering that I am a beginner.

    
asked by anonymous 04.01.2019 / 19:18

3 answers

2

If you notice you will see that there are some lines that always repeat in all conditions like:

Produto::orderBy('credito', 'DESC')
->where('id_subcategoria', $subcategoria)
->where('visivel_site', self::SIM)
->where('credito', '<=', Utils::calculaPorcentagem($porcentagem, $credito))

Utils::calculaPorcentagem($porcentagem, $credito);

function($query) use ($parcela, porcentagem) {
    $query->where('parcela', '<=', $porcentagem);
}

Knowing this you can move them out of each if and add in the conditions just a variable that summarizes the action, see;

$cotas = Produto::orderBy('credito', 'DESC')
    ->where('id_subcategoria', $subcategoria)
    ->where('visivel_site', self::SIM)
    ->where('credito', '<=', Utils::calculaPorcentagem($porcentagem, $credito))

$porcentagem = Utils::calculaPorcentagem($porcentagem, $credito);

$parcelaQuery = function($query) use ($parcela, porcentagem) {
    $query->where('parcela', '<=', $porcentagem);
}


// você pode usar o operador ! para inverter a condição
if (!$entrada and !$parcela) {
    $cotas->where('credito', '<=', $porcentagem);
} else if (!$parcela) {
    $cotas->where('entrada', '<=', $porcentagem);
} else if (!$entrada) {
    $cotas->whereHas('saldo', $parcelaQuery);
} else {
    $cotas->where('entrada', '<=', $porcentagem)->whereHas('saldo', $parcelaQuery)
}

return $cotas->get();
    
04.01.2019 / 19:40
2

You can do it this way:

$calculaPorcentagem = Utils::calculaPorcentagem($porcentagem, $credito);

$query = Produto::orderBy('credito', 'DESC')
        ->where('id_subcategoria', $subcategoria)
        ->where('visivel_site', self::SIM)
        ->where('credito', '<=', $calculaPorcentagem);

if (is_null($entrada) and is_null($parcela))
    return $query->get();

if (is_null($parcela)) 
    return $query->where('entrada', '<=', $calculaPorcentagem)->get();

$query = is_null($entrada) ? $query : $query->where('entrada', '<=', $calculaPorcentagem);

return $query->whereHas('saldo', function ($query) {
            $query->where('parcela', '<=', $calculaPorcentagem);
        })->get();

So you put in a variable and can reuse in the next steps.

    
04.01.2019 / 19:32
0

/ p>

$cotas = Produto::orderBy('credito', 'DESC')
        ->where('id_subcategoria', $subcategoria)
        ->where('visivel_site', self::SIM)
        ->where('credito', '<=', Utils::calculaPorcentagem($porcentagem, $credito));

    if (isset($entrada)) {
        $cotas = $cotas
            ->where('entrada', '<=', Utils::calculaPorcentagem($porcentagem, $entrada));
    }
    if (isset($parcela)) {
        $cotas = $cotas
            ->whereHas('saldo', function ($newquery) use ($parcela, $porcentagem) {
                $newquery->where('parcela', '<=', Utils::calculaPorcentagem($porcentagem, $parcela));
            });
    }

    return $cotas->get();
    
05.01.2019 / 19:03