Skip to content

Commit

Permalink
Merge branch 'hotfix/0.19.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
polosson committed Oct 28, 2022
2 parents cdc1cef + 1f858f0 commit 4a0fc4e
Show file tree
Hide file tree
Showing 10 changed files with 489 additions and 620 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Tous les changements notables sur le projet sont documentés dans ce fichier.

Ce projet adhère au principe du [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.19.3 (2022-10-28)

- Améliore le temps de chargement des événements dans le calendrier (#210).

## 0.19.2 (2022-07-29)

- Un problème lors de la création du premier utilisateur dans le wizard d'installation a été corrigé (#367).
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.19.2
0.19.3
4 changes: 4 additions & 0 deletions client/src/components/Timeline/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ export default {
moveTo(time, options) {
this.timeline.moveTo(time, options);
},

zoomIn(percentage, options) {
this.timeline.zoomIn(percentage, options);
},
},
render() {
const { loading, groups } = this;
Expand Down
39 changes: 22 additions & 17 deletions client/src/pages/Calendar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import CalendarCaption from './components/Caption';
import { formatEvent, getDefaultPeriod } from './_utils';

const ONE_DAY = 1000 * 3600 * 24;
const FETCH_DELTA_DAYS = 3;
const MAX_ZOOM_MONTH = 3;

// @vue/component
export default {
Expand All @@ -24,11 +26,12 @@ export default {
return {
hasCriticalError: false,
isLoading: false,
isFetched: false,
isSaving: false,
isDeleting: false,
isOverItem: false,
fetchStart: moment(start).subtract(8, 'days').startOf('day'),
fetchEnd: moment(end).add(1, 'months').endOf('month'),
fetchStart: moment(start).subtract(FETCH_DELTA_DAYS, 'days').startOf('day'),
fetchEnd: moment(end).add(FETCH_DELTA_DAYS, 'days').endOf('day'),
isModalOpened: false,
filterMissingMaterial: false,
parkId: parkFilter ? Number.parseInt(parkFilter, 10) : null,
Expand Down Expand Up @@ -56,7 +59,7 @@ export default {
end,
selectable: !isVisitor,
zoomMin: ONE_DAY * 7,
zoomMax: ONE_DAY * 6 * 30,
zoomMax: ONE_DAY * 30 * MAX_ZOOM_MONTH,
};
},

Expand All @@ -83,9 +86,6 @@ export default {
return events;
},
},
mounted() {
this.getEventsData();
},
methods: {
// ------------------------------------------------------
// -
Expand Down Expand Up @@ -118,18 +118,17 @@ export default {
localStorage.setItem('calendarEnd', dates.end.format('YYYY-MM-DD HH:mm:ss'));
this.$refs.Header.changePeriod(dates);

let needFetch = false;
if (this.fetchStart.isAfter(dates.start)) {
this.fetchStart = moment(dates.start).subtract(8, 'days').startOf('day');
needFetch = true;
}

if (this.fetchEnd.isBefore(dates.end)) {
this.fetchEnd = moment(dates.end).add(1, 'months').endOf('month');
needFetch = true;
}
const newFetchStart = moment(dates.start).subtract(FETCH_DELTA_DAYS, 'days').startOf('day');
const newFetchEnd = moment(dates.end).add(FETCH_DELTA_DAYS, 'days').endOf('day');

const needFetch = (
!this.isFetched ||
newFetchStart.isBefore(this.fetchStart) ||
newFetchEnd.isAfter(this.fetchEnd)
);
if (needFetch) {
this.fetchStart = newFetchStart;
this.fetchEnd = newFetchEnd;
this.getEventsData();
}
},
Expand Down Expand Up @@ -284,7 +283,13 @@ export default {
try {
const { data } = await apiEvents.all(params);
this.events = data;
} catch {
this.isFetched = true;
} catch (error) {
const { status } = error.response ?? { status: 0 };
if (status === 416) {
this.$refs.calendarTimeline.zoomIn(1, { animation: false });
return;
}
this.hasCriticalError = true;
} finally {
this.isLoading = false;
Expand Down
51 changes: 41 additions & 10 deletions server/src/App/Controllers/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Robert2\API\Models\Park;
use Robert2\API\Services\Auth;
use Robert2\API\Services\I18n;
use Slim\Exception\HttpException;
use Slim\Exception\HttpNotFoundException;
use Slim\Http\Response;
use Slim\Http\ServerRequest as Request;
Expand Down Expand Up @@ -59,25 +60,55 @@ public function getAll(Request $request, Response $response): Response

$startDate = $request->getQueryParam('start', null);
$endDate = $request->getQueryParam('end', null);
$deleted = (bool)$request->getQueryParam('deleted', false);
$withMaterials = (bool)$request->getQueryParam('with-materials', false);

// - Limitation de la période récupérable (en mois)
$maxMonth = 3.5;
$maxTime = 60 * 60 * 24 * 30 * $maxMonth;
$diffTime = strtotime($endDate) - strtotime($startDate);
if ($diffTime > $maxTime) {
throw new HttpException(
$request,
sprintf('The retrieval period for events may not exceed %s months.', $maxMonth),
416
);
}

$query = Event::inPeriod($startDate, $endDate)
->with('Beneficiaries')
->with('Technicians');
->with('Technicians')
->with(['Materials' => function ($q) {
$q->orderBy('name', 'asc');
}]);

$deleted = (bool)$request->getQueryParam('deleted', false);
if ($deleted) {
$query->onlyTrashed();
}

if ($withMaterials) {
$query->with(['Materials' => function ($q) {
$q->orderBy('name', 'asc');
}]);
$events = $query->get();

$concurrentEvents = Event::inPeriod($startDate, $endDate)
->with('Materials')
->get()->toArray();

foreach ($events as $event) {
$event->__cachedConcurrentEvents = array_values(
array_filter($concurrentEvents, function ($otherEvent) use ($event) {
$startDate = new \DateTime($event->start_date);
$otherStartDate = new \DateTime($otherEvent['start_date']);
$endDate = new \DateTime($event->end_date);
$otherEndDate = new \DateTime($otherEvent['end_date']);
return (
$event->id !== $otherEvent['id'] &&
$startDate <= $otherEndDate &&
$endDate >= $otherStartDate
);
})
);
}

$data = $query->get()
->each->setAppends([
$data = $events->each
->setAppends([
'has_missing_materials',
'has_not_returned_materials',
])
Expand All @@ -86,7 +117,7 @@ public function getAll(Request $request, Response $response): Response
$useMultipleParks = Park::count() > 1;
foreach ($data as $index => $event) {
$data[$index]['parks'] = $useMultipleParks
? Event::getParks($event['id'])
? Event::getParks($event['materials'])
: null;
}

Expand Down
2 changes: 1 addition & 1 deletion server/src/App/Controllers/MaterialController.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public function getEvents(Request $request, Response $response): Response

$collection[] = array_replace($event->toArray(), [
'parks' => $useMultipleParks
? Event::getParks($event['id'])
? Event::getParks($event['materials'])
: null
]);
}
Expand Down
12 changes: 5 additions & 7 deletions server/src/App/Models/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class Event extends BaseModel
use WithPdf;
use Cache;

public $__cachedConcurrentEvents = null;

protected $orderField = 'start_date';

protected $allowedSearchFields = ['title', 'start_date', 'end_date', 'location'];
Expand Down Expand Up @@ -334,6 +336,7 @@ public function missingMaterials(): ?array
$this->start_date,
$this->end_date,
$this->exists ? $this->id : null,
$this->__cachedConcurrentEvents
);

$missingMaterials = [];
Expand All @@ -350,16 +353,11 @@ public function missingMaterials(): ?array
: null;
}

public static function getParks(int $id): array
public static function getParks(array $materials): array
{
$event = static::with('Materials')->find($id);
if (!$event) {
return [];
}

$materialParks = array_map(function ($material) {
return $material['park_id'];
}, $event['materials']);
}, $materials);

return array_values(array_unique($materialParks));
}
Expand Down
28 changes: 16 additions & 12 deletions server/src/App/Models/Material.php
Original file line number Diff line number Diff line change
Expand Up @@ -466,30 +466,33 @@ public static function recalcQuantitiesForPeriod(
array $data,
?string $start = null,
?string $end = null,
?int $exceptEventId = null
?int $exceptEventId = null,
?array $concurrentEvents = null
): array {
if (empty($data)) {
return [];
}

$events = [];
if (!empty($start) || !empty($end)) {
$query = Event::inPeriod($start, $end);
if ($exceptEventId) {
$query = $query->where('id', '!=', $exceptEventId);
if ($concurrentEvents === null) {
$concurrentEvents = [];
if (!empty($start) || !empty($end)) {
$query = Event::inPeriod($start, $end);
if ($exceptEventId) {
$query = $query->where('id', '!=', $exceptEventId);
}
$concurrentEvents = $query->with('Materials')->get()->toArray();
}
$events = $query->with('Materials')->get()->toArray();
}

$periods = splitPeriods($events);
$periods = splitPeriods($concurrentEvents);

foreach ($data as &$material) {
$quantityPerPeriod = [0];
foreach ($periods as $periodIndex => $period) {
$overlapEvents = array_filter($events, function ($event) use ($period) {
$overlapEvents = array_filter($concurrentEvents, function ($concurrentEvent) use ($period) {
return (
strtotime($event['start_date']) < strtotime($period[1]) &&
strtotime($event['end_date']) > strtotime($period[0])
strtotime($concurrentEvent['start_date']) < strtotime($period[1]) &&
strtotime($concurrentEvent['end_date']) > strtotime($period[0])
);
});

Expand All @@ -504,9 +507,10 @@ public static function recalcQuantitiesForPeriod(
$quantityPerPeriod[$periodIndex] += $eventMaterial['pivot']['quantity'];
}
}
$usedCount = max($quantityPerPeriod);

$remainingQuantity = (int)$material['stock_quantity'] - (int)$material['out_of_order_quantity'];
$material['remaining_quantity'] = max($remainingQuantity - max($quantityPerPeriod), 0);
$material['remaining_quantity'] = max($remainingQuantity - $usedCount, 0);
}

return $data;
Expand Down
Loading

0 comments on commit 4a0fc4e

Please sign in to comment.