Skip to content

Commit aef9cd8

Browse files
Merge pull request #27 from salhdev/feature-changedatecolumn
Added configurable date column
2 parents ed118eb + c461efd commit aef9cd8

10 files changed

+398
-3
lines changed

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,46 @@ class MyProjectableModel extends Model
6161
];
6262
}
6363
```
64+
If you want to use a different date field from your Model instead of created_at then do the following :
65+
1) Make sure the field is casted to Carbon
66+
67+
```php
68+
use App\Models\Projections\MyProjection;
69+
use TimothePearce\TimeSeries\Projectable;
70+
71+
class MyProjectableModel extends Model
72+
{
73+
use Projectable;
74+
75+
protected $casts = [
76+
'other_date_time' => 'datetime:Y-m-d H:00',
77+
];
78+
79+
protected array $projections = [
80+
MyProjection::class,
81+
];
82+
}
83+
```
84+
2) Add the dateColumn field in your Projection
85+
```php
86+
namespace App\Models\Projections;
87+
88+
use Illuminate\Database\Eloquent\Model;
89+
use TimothePearce\TimeSeries\Contracts\ProjectionContract;
90+
use TimothePearce\TimeSeries\Models\Projection;
91+
92+
class MyProjection extends Projection implements ProjectionContract
93+
{
94+
/**
95+
* The projected periods.
96+
*/
97+
public array $periods = [];
98+
99+
public string $dateColumn = 'other_date_time';
100+
....
101+
102+
```
103+
64104

65105
### Implement a Projection
66106

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"php": "^8.0"
2727
},
2828
"require-dev": {
29+
"brianium/paratest": "^6.11",
2930
"nunomaduro/collision": "^6.0",
3031
"nunomaduro/larastan": "^2.0.1",
3132
"orchestra/testbench": "^7.0",

src/Projector.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@
99

1010
class Projector
1111
{
12+
public string $dateColumn = 'created_at';
13+
1214
public function __construct(
1315
protected Model $projectedModel,
1416
protected string $projectionName,
1517
protected string $eventName,
1618
) {
19+
$projection = (new $this->projectionName());
20+
if (isset($projection->dateColumn)) {
21+
$this->dateColumn = $projection->dateColumn;
22+
}
1723
}
1824

1925
/**
@@ -104,7 +110,7 @@ private function findProjection(string $period): Projection|null
104110
['projection_name', $this->projectionName],
105111
['key', $this->hasKey() ? $this->key() : null],
106112
['period', $period],
107-
['start_date', app(TimeSeries::class)->resolveFloorDate($this->projectedModel->created_at, $period)],
113+
['start_date', app(TimeSeries::class)->resolveFloorDate($this->projectedModel->{$this->dateColumn}, $period)],
108114
]);
109115
}
110116

@@ -117,7 +123,7 @@ private function createProjection(string $period): void
117123
'projection_name' => $this->projectionName,
118124
'key' => $this->hasKey() ? $this->key() : null,
119125
'period' => $period,
120-
'start_date' => app(TimeSeries::class)->resolveFloorDate($this->projectedModel->created_at, $period),
126+
'start_date' => app(TimeSeries::class)->resolveFloorDate($this->projectedModel->{$this->dateColumn}, $period),
121127
'content' => $this->mergeProjectedContent((new $this->projectionName())->defaultContent(), $period),
122128
]);
123129
}
@@ -193,7 +199,7 @@ private function resolveCallableMethod(array $content, string $period): array
193199
*/
194200
private function resolveStartDate(string $periodType, int $quantity): Carbon
195201
{
196-
$startDate = $this->projectedModel->created_at->floorUnit($periodType, $quantity);
202+
$startDate = $this->projectedModel->{$this->dateColumn}->floorUnit($periodType, $quantity);
197203

198204
if (in_array($periodType, ['week', 'weeks'])) {
199205
$startDate->startOfWeek(config('time-series.beginning_of_the_week'));
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace TimothePearce\TimeSeries\Tests\Models\Projections;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use TimothePearce\TimeSeries\Contracts\ProjectionContract;
7+
use TimothePearce\TimeSeries\Models\Projection;
8+
9+
class TableReservationPerDiningDayProjection extends Projection implements ProjectionContract
10+
{
11+
/**
12+
* Lists the time intervals used to compute the projections.
13+
*/
14+
public array $periods = ['1 day'];
15+
16+
public string $dateColumn = 'reservation_date';
17+
18+
/**
19+
* The default projection content.
20+
*/
21+
public function defaultContent(): array
22+
{
23+
return [
24+
'total_people' => 0,
25+
'number_reservations' => 0,
26+
];
27+
}
28+
29+
/**
30+
* Computes the content when a projectable model is created.
31+
*/
32+
public function projectableCreated(array $content, Model $model): array
33+
{
34+
return [
35+
'total_people' => $content['total_people'] += $model->number_people,
36+
'number_reservations' => $content['number_reservations'] + 1,
37+
];
38+
}
39+
40+
/**
41+
* Computes the content when a projectable model is deleted.
42+
*/
43+
public function projectableDeleted(array $content, Model $model): array
44+
{
45+
return [
46+
'total_people' => $content['total_people'] -= $model->number_people,
47+
'number_reservations' => $content['number_reservations'] - 1,
48+
];
49+
}
50+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace TimothePearce\TimeSeries\Tests\Models\Projections;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use TimothePearce\TimeSeries\Contracts\ProjectionContract;
7+
use TimothePearce\TimeSeries\Models\Projection;
8+
9+
class TableReservationPerDiningDayProjectionWithKey extends TableReservationPerDiningDayProjection
10+
{
11+
/**
12+
* The key used to query the projection.
13+
*/
14+
public static function key(Model $model): string
15+
{
16+
return (string)$model->table_id;
17+
}
18+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace TimothePearce\TimeSeries\Tests\Models\Projections;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use TimothePearce\TimeSeries\Contracts\ProjectionContract;
7+
use TimothePearce\TimeSeries\Models\Projection;
8+
9+
class TableReservationPerMadeDayProjection extends TableReservationPerDiningDayProjection
10+
{
11+
public function __construct() {
12+
$this->dateColumn = 'reservation_made_date';
13+
}
14+
}

tests/Models/TableReservation.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace TimothePearce\TimeSeries\Tests\Models;
4+
5+
use Illuminate\Database\Eloquent\Factories\HasFactory;
6+
use Illuminate\Database\Eloquent\Model;
7+
use Illuminate\Database\Eloquent\SoftDeletes;
8+
use TimothePearce\TimeSeries\Models\Traits\Projectable;
9+
use TimothePearce\TimeSeries\Tests\Models\Projections\TableReservationPerMadeDayProjection;
10+
use TimothePearce\TimeSeries\Tests\Models\Projections\TableReservationPerDiningDayProjection;
11+
12+
class TableReservation extends Model
13+
{
14+
use HasFactory;
15+
use Projectable;
16+
use SoftDeletes;
17+
18+
protected $casts = [
19+
'reservation_date' => 'datetime:Y-m-d',
20+
'reservation_made_date' => 'datetime:Y-m-d H:00',
21+
];
22+
/**
23+
* The projections list.
24+
*/
25+
protected array $projections = [
26+
TableReservationPerMadeDayProjection::class,
27+
TableReservationPerDiningDayProjection::class,
28+
];
29+
}

0 commit comments

Comments
 (0)