'float', 'rate' => 'float', 'zone' => 'integer', 'effective_at' => 'datetime', ]; /** * Scope: get the latest rates effective on or before a given date. */ public function scopeLatestEffective(Builder $q, ?\DateTimeInterface $at = null): Builder { $at ??= now(); return $q->where('effective_at', '<=', $at) ->orderByDesc('effective_at'); } /** * Look up the applicable rate for a given weight/zone. * Rounds UP to the next available weight tier if exact match not found. * * @return static|null */ public static function lookup( string $direction, string $serviceType, float $weight, int $zone, string $currency = 'AED', ?\DateTimeInterface $at = null ): ?self { $at ??= now(); // Try exact weight first $entry = self::where('direction', $direction) ->where('service_type', $serviceType) ->where('weight', $weight) ->where('zone', $zone) ->where('currency', $currency) ->where('effective_at', '<=', $at) ->orderByDesc('effective_at') ->first(); if ($entry) return $entry; // Otherwise: round UP to the next available weight tier // (this is correct for shipping — a 2.3 kg parcel pays the 2.5 kg rate) return self::where('direction', $direction) ->where('service_type', $serviceType) ->where('weight', '>=', $weight) ->where('zone', $zone) ->where('currency', $currency) ->where('effective_at', '<=', $at) ->orderBy('weight') ->orderByDesc('effective_at') ->first(); } }