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);
}