Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Date Scopes Laravel Package

laracraft-tech/laravel-date-scopes

Add powerful, ready-made date query scopes to Laravel Eloquent models. Use the DateScopes trait to query records for today, last week, month-to-date, last year (with custom start dates), and more—fully chainable with builder methods and aggregations.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require laracraft-tech/laravel-date-scopes
    

    No additional configuration is required for basic usage.

  2. First Use Case: Apply the DateScopes trait to any Eloquent model:

    use LaracraftTech\LaravelDateScopes\DateScopes;
    
    class Transaction extends Model
    {
        use DateScopes;
    }
    

    Now query records using built-in scopes:

    // Get today's transactions
    Transaction::ofToday();
    
    // Get last week's transactions
    Transaction::ofLastWeek();
    
  3. Where to Look First:


Implementation Patterns

Common Workflows

  1. Basic Date Filtering:

    // Filter by predefined periods
    $today = Transaction::ofToday();
    $lastWeek = Transaction::ofLastWeek();
    
    // Custom periods
    $last30Days = Transaction::ofLastDays(30);
    
  2. Chaining with Aggregations:

    // Sum amounts for today
    $todayTotal = Transaction::ofToday()->sum('amount');
    
    // Average for last month
    $monthAvg = Transaction::ofLastMonth()->avg('amount');
    
  3. Custom Columns:

    // Use a non-standard column (e.g., 'approved_at')
    $approvedToday = Transaction::ofToday(column: 'approved_at');
    
  4. Custom Start Dates:

    // Filter from a specific date
    $year2020 = Transaction::ofLastYear(startFrom: '2020-01-01');
    
  5. Inclusive/Exclusive Ranges:

    // Override global default (e.g., include today)
    $inclusiveLastWeek = Transaction::ofLastWeek(customRange: DateRange::INCLUSIVE);
    
  6. Period-to-Date Queries:

    // Get data from start of year to now
    $yearToDate = Transaction::yearToDate();
    

Integration Tips

  • API Controllers: Use scopes to filter resources dynamically:

    public function index(Request $request)
    {
        $query = Transaction::query();
        if ($request->has('period')) {
            $query->{$request->period}(); // e.g., "ofLastWeek"
        }
        return $query->get();
    }
    
  • Jobs/Commands: Schedule reports for specific periods:

    // In a scheduled job
    $dailyRevenue = Transaction::ofToday()->sum('amount');
    
  • Views: Pass scoped data to Blade templates:

    $weeklySales = Transaction::ofLastWeek()->get();
    return view('reports.weekly', compact('weeklySales'));
    
  • Testing: Mock dates for consistent test results:

    use Carbon\Carbon;
    
    beforeEach(function () {
        Carbon::setTestNow(Carbon::now()->startOfDay());
    });
    

Gotchas and Tips

Pitfalls

  1. Inclusive vs. Exclusive Ranges:

    • Default is exclusive (e.g., ofLastWeek excludes today).
    • Override globally via config or per-scope:
      Transaction::ofLastWeek(customRange: DateRange::INCLUSIVE);
      
    • Tip: Clarify requirements with stakeholders—business logic may vary (e.g., "last week" in analytics vs. "this week").
  2. Centuries/Millenniums:

    • Follows Wikipedia conventions (e.g., "last century" = 1901–2000).
    • Unexpected ranges may break assumptions. Document edge cases in your code.
  3. Custom Columns:

    • Ensure the column exists in the database and is nullable if needed.
    • Gotcha: Forgetting to update $table->timestamp('custom_column') in migrations.
  4. Time Zones:

    • Scopes use the system’s default time zone. Explicitly set time zones if needed:
      Transaction::ofToday()->setTimeZone('America/New_York');
      
  5. Performance:

    • Avoid overly broad scopes (e.g., ofLastDecade) on large tables without indexing.
    • Tip: Add indexes to date columns:
      $table->timestamp('created_at')->index();
      
  6. Chaining Conflicts:

    • Scopes modify the query builder. Chain carefully to avoid unintended overlaps:
      // ❌ Avoid: May return empty results if today is excluded
      Transaction::ofLastWeek()->ofToday();
      
    • Fix: Use orWhere or rebuild the query.

Debugging Tips

  1. Log Raw Queries: Enable query logging to verify scope behavior:

    DB::enableQueryLog();
    Transaction::ofLastWeek()->get();
    dd(DB::getQueryLog());
    
  2. Test Edge Cases:

    • Test around midnight/year boundaries (e.g., ofLastYear on Jan 1).
    • Example:
      Carbon::setTestNow(Carbon::parse('2023-01-01'));
      $result = Transaction::ofLastYear()->count(); // Should return 0
      
  3. Custom Scope Validation:

    • Validate custom startFrom dates:
      if (!Carbon::parse($startFrom)->isValid()) {
          throw new \InvalidArgumentException("Invalid date format");
      }
      

Extension Points

  1. Add Custom Scopes: Extend the trait or create a new one:

    trait CustomDateScopes
    {
        public function scopeOfLastBusinessDays($query, $days)
        {
            // Custom logic to exclude weekends
        }
    }
    
  2. Override Default Behavior: Publish and modify the config:

    php artisan vendor:publish --tag="date-scopes-config"
    

    Then update config/date-scopes.php:

    'default_range' => DateRange::INCLUSIVE->value,
    
  3. Localize Date Logic: Override date calculations for specific models:

    class FiscalYearModel extends Model
    {
        use DateScopes;
    
        public function scopeOfFiscalYear($query)
        {
            // Custom fiscal year logic
        }
    }
    
  4. Use with Soft Deletes: Scopes work with soft-deleted models, but ensure withTrashed() is used if needed:

    Transaction::withTrashed()->ofLastWeek()->get();
    

Pro Tips

  • Combine with API Resources:

    public function toArray($request)
    {
        return [
            'today' => Transaction::ofToday()->count(),
            'last_week' => Transaction::ofLastWeek()->count(),
        ];
    }
    
  • Laravel Nova: Use scopes in Nova toolbars for quick filtering:

    Toolbar::make()
        ->append(
            Link::make('Today', route('transactions.today'))
                ->asMethod('GET')
                ->canSee(fn () => auth()->check())
        );
    
  • Dynamic Scopes: Create a dynamic scope resolver:

    public function scopeOfPeriod($query, $period)
    {
        $method = "of{$period}";
        return $method ? $query->$method() : $query;
    }
    

    Usage:

    Transaction::ofPeriod('LastWeek');
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport