I have a model named ClientDiscountRate, which naturally corresponds to a table.
I am developing a method to allow the creation of a new ClientDiscountRate. However, I am facing a problem: the client_discount_rates table has from and to columns, and I need to ensure that the new rate does not overlap with any existing rates.
Both from and to must be integers, with from being smaller than to.
For instance, if I already have a range from 4 to 6, no overlapping ranges means the new rate cannot have a from or to value of 4, 5, or 6. It also means the new rate cannot encompass 4-6, such as having from: 3, to: 7. The new range can be before or after the existing range, but it cannot contain, be contained by, or intersect with the existing range in any way.
Moreover, I could have multiple existing ranges. So, if I have ranges 4-6 and 10-20, the overlapping check must apply the same logic to both ranges - the new range cannot overlap, contain, or be contained by either existing range.
I have written the following code, but I am unsure if it is the most efficient approach:
$from = $requestData['from'];
$to = $requestData['to'];
$matching = ClientDiscountRate::where('client_id', $client->id)
->where('from', '<=', $from)
->where('to', '>=', $from)
->first();
if ($matching) return response()->json(['error' => 'this range overlaps an existing one - from'], 400);
$matching = ClientDiscountRate::where('client_id', $client->id)
->where('from', '<=', $to)
->where('to', '>=', $to)
->first();
if ($matching) return response()->json(['error' => 'this range overlaps an existing one - to'], 400);
$matching = ClientDiscountRate::where('client_id', $client->id)
->where('from', '>=', $from)
->where('from', '<=', $to)
->first();
if ($matching) return response()->json(['error' => 'this range contains an existing one'], 400);
$matching = ClientDiscountRate::where('client_id', $client->id)
->where('to', '>=', $from)
->where('to', '<=', $to)
->first();
if ($matching) return response()->json(['error' => 'this range contains an existing one'], 400);
Is the above a sensible way to check for undesirable overlaps in the from and to fields?
The rule to respect is that for all the from in the database that is less or equal your $to, you have to find that all the corresponding to for those from have to be less than your $from, if it's not the case then you have an overlapping ranges.
$from = $requestData['from'];
$to = $requestData['to'];
$matching = ClientDiscountRate::where('client_id', $client->id)
->where('from', '<=', $to)
->where('to', '>=', $from)
->exists();
if ($matching) {
return response()->json(['error' => 'this range overlaps an existing one'], 400);
}