Skip to content

Commit

Permalink
🚸 Change trip destination after checkin (#1103)
Browse files Browse the repository at this point in the history
fixes #427
  • Loading branch information
MrKrisKrisu authored Oct 15, 2022
1 parent f22e2ae commit a690025
Show file tree
Hide file tree
Showing 17 changed files with 205 additions and 79 deletions.
5 changes: 5 additions & 0 deletions .idea/trwl.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions app/Http/Controllers/Backend/Transport/StationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
use App\Exceptions\HafasException;
use App\Http\Controllers\Controller;
use App\Http\Controllers\HafasController;
use App\Models\TrainCheckin;
use App\Models\TrainStation;
use App\Models\TrainStopover;
use App\Models\User;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Collection;
Expand Down Expand Up @@ -61,4 +63,18 @@ public static function getLatestArrivals(User $user, int $maxCount = 5): Collect
->limit($maxCount)
->get();
}

public static function getAlternativeDestinationsForCheckin(TrainCheckin $checkin): Collection {
return $checkin->HafasTrip->stopoversNEW
->filter(function(TrainStopover $stopover) use ($checkin) {
return $stopover->arrival_planned->isAfter($checkin->departure);
})
->map(function(TrainStopover $stopover) {
return [
'id' => $stopover->id,
'name' => $stopover->trainStation->name,
'arrival_planned' => $stopover->arrival_planned->format('H:i'),
];
});
}
}
33 changes: 33 additions & 0 deletions app/Http/Controllers/Backend/Transport/TrainCheckinController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Http\Controllers\Backend\Transport;

use App\Enum\Business;
use App\Enum\PointReason;
use App\Enum\StatusVisibility;
use App\Events\UserCheckedIn;
use App\Exceptions\Checkin\AlreadyCheckedInException;
Expand All @@ -21,6 +22,7 @@
use App\Models\Status;
use App\Models\TrainCheckin;
use App\Models\TrainStation;
use App\Models\TrainStopover;
use App\Models\User;
use App\Notifications\UserJoinedConnection;
use Carbon\Carbon;
Expand Down Expand Up @@ -187,4 +189,35 @@ private static function createTrainCheckin(
throw $exception; // Other scenarios are not handled, so rethrow the exception
}
}

public static function changeDestination(TrainCheckin $checkin, TrainStopover $newDestinationStopover): PointReason {
if ($newDestinationStopover->arrival_planned->isBefore($checkin->origin_stopover->arrival_planned)
|| $newDestinationStopover->is($checkin->origin_stopover)
|| !$checkin->HafasTrip->stopoversNEW->contains('id', $newDestinationStopover->id)
) {
throw new InvalidArgumentException();
}

$newDistance = GeoController::calculateDistance(
hafasTrip: $checkin->HafasTrip,
origin: $checkin->origin_stopover,
destination: $newDestinationStopover,
);

$pointsResource = PointsCalculationController::calculatePoints(
distanceInMeter: $newDistance,
hafasTravelType: $checkin->HafasTrip->category,
departure: $checkin->origin_stopover->departure,
arrival: $newDestinationStopover->arrival,
);

$checkin->update([
'arrival' => $newDestinationStopover->arrival_planned->toIso8601String(),
'destination' => $newDestinationStopover->trainStation->ibnr,
'points' => $pointsResource['points'],
]);

return PointReason::tryFrom($pointsResource['calculation']['reason']);
}

}
68 changes: 68 additions & 0 deletions app/Http/Controllers/Frontend/Transport/StatusController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace App\Http\Controllers\Frontend\Transport;

use App\Enum\Business;
use App\Enum\PointReason;
use App\Enum\StatusVisibility;
use App\Exceptions\PermissionException;
use App\Http\Controllers\Backend\Transport\TrainCheckinController;
use App\Http\Controllers\Controller;
use App\Models\Status;
use App\Models\TrainStopover;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rules\Enum;

class StatusController extends Controller
{

public function updateStatus(Request $request): JsonResponse|RedirectResponse {
$validated = $request->validate([
'statusId' => ['required', 'exists:statuses,id'],
'body' => ['nullable', 'max:280'],
'business_check' => ['required', new Enum(Business::class)],
'checkinVisibility' => ['required', new Enum(StatusVisibility::class)],
'destinationStopoverId' => ['nullable', 'exists:train_stopovers,id'],
]);

try {
$status = Status::findOrFail($validated['statusId']);
$this->authorize('update', $status);
$status->update([
'body' => $validated['body'] ?? null,
'business' => Business::from($validated['business_check']),
'visibility' => StatusVisibility::from($validated['checkinVisibility']),
]);

if (isset($validated['destinationStopoverId'])
&& $validated['destinationStopoverId'] != $status->trainCheckin->destination_stopover->id) {
$pointReason = TrainCheckinController::changeDestination(
checkin: $status->trainCheckin,
newDestinationStopover: TrainStopover::findOrFail($validated['destinationStopoverId']),
);
$status->fresh();

return redirect()->route('statuses.get', ['id' => $status->id])
->with('checkin-success', [
'reason' => 'status-updated',
'distance' => $status->trainCheckin->distance,
'duration' => $status->trainCheckin->duration,
'points' => $status->trainCheckin->points,
'lineName' => $status->trainCheckin->HafasTrip->linename,
'alsoOnThisConnection' => $status->trainCheckin->alsoOnThisConnection,
'event' => $status->trainCheckin->event,
'forced' => false,
'pointsCalculationReason' => $pointReason,
]);
}

return redirect()->route('statuses.get', ['id' => $status->id])
->with('success', __('status.update.success'));
} catch (ModelNotFoundException|PermissionException) {
return redirect()->back()->with('alert-danger', __('messages.exception.general'));
}
}
}
26 changes: 0 additions & 26 deletions app/Http/Controllers/FrontendStatusController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace App\Http\Controllers;

use App\Enum\Business;
use App\Enum\StatusVisibility;
use App\Exceptions\PermissionException;
use App\Exceptions\StatusAlreadyLikedException;
use App\Http\Controllers\Backend\EventController as EventBackend;
Expand All @@ -23,7 +21,6 @@
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Illuminate\Validation\Rules\Enum;
use InvalidArgumentException;

/**
Expand Down Expand Up @@ -78,29 +75,6 @@ public function DeleteStatus(Request $request): JsonResponse|RedirectResponse {
return response()->json(['message' => __('controller.status.delete-ok')]);
}

public function EditStatus(Request $request): JsonResponse|RedirectResponse {
$validated = $this->validate($request, [
'statusId' => ['required', 'exists:statuses,id'],
'body' => ['nullable', 'max:280'],
'business_check' => ['required', new Enum(Business::class)],
'checkinVisibility' => ['required', new Enum(StatusVisibility::class)],
]);

try {
$editStatusResponse = StatusBackend::EditStatus(
user: Auth::user(),
statusId: $validated['statusId'],
body: $validated['body'] ?? null,
business: Business::from($validated['business_check']),
visibility: StatusVisibility::from($validated['checkinVisibility']),
);
} catch (ModelNotFoundException|PermissionException) {
return redirect()->back();
}

return response()->json(['new_body' => $editStatusResponse->body], 200);
}

public function createLike(Request $request) {
$validated = $request->validate([
'statusId' => ['required', 'exists:statuses,id']
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Resources/PointsCalculationResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function toArray($request): array {
'base' => $this['calculation']['base'],
'distance' => $this['calculation']['distance'], //TODO: This isn't the distance! Should be renamed.
'factor' => $this['calculation']['factor'] ?? 1,
'reason' => $this['calculation']['reason'] ?? PointReason::IN_TIME
'reason' => $this['calculation']['reason'] ?? PointReason::IN_TIME->value,
],
'additional' => AdditionalPointsResource::collection($this['additional'])
];
Expand Down
58 changes: 31 additions & 27 deletions resources/js/components/business-check-in.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
let statusBusiness;
let statusVisibility;
let statusBody;
let statusId = 0;
let statusBodyElement = $("#status-body");

let businessCheckInput = $("#business_check");
let businessButton = $("#businessDropdownButton");
const businessIcons = ["fa-user", "fa-briefcase", "fa-building"];
Expand Down Expand Up @@ -32,31 +26,41 @@ $(".trwl-visibility-item").on("click", function (event) {
$(document).on("click", ".edit", function (event) {
event.preventDefault();

statusId = event.currentTarget.dataset.trwlStatusId;
statusBody = document.getElementById("status-" + statusId).dataset.trwlStatusBody;
statusBusiness = document.getElementById("status-" + statusId).dataset.trwlBusinessId;
statusVisibility = document.getElementById("status-" + statusId).dataset.trwlVisibility;
statusBodyElement.val(statusBody);
let statusId = event.currentTarget.dataset.trwlStatusId;
let dataset = document.getElementById("status-" + statusId).dataset;

document.querySelector("#status-update input[name='statusId']").value = statusId;
document.querySelector("#status-update textarea[name='body']").value = dataset.trwlStatusBody;

let statusBusiness = dataset.trwlBusinessId;
let statusVisibility = dataset.trwlVisibility;
businessCheckInput.val(statusBusiness);
visibilityFormInput.val(statusVisibility);
setIconForDropdown(statusBusiness, businessButton, businessCheckInput, businessIcons);
setIconForDropdown(statusVisibility, visibilityButton, visibilityFormInput, visibilityIcons);
$("#edit-modal").modal("show");
document.querySelector('#body-length').innerText = document.querySelector('#status-body').value.length;
});

$(document).on("click", "#modal-trwl-edit-save", function () {
$.ajax({
method: "POST",
url: urlEdit,
data: {
body: statusBodyElement.val(),
statusId: statusId,
business_check: businessCheckInput.val(),
checkinVisibility: visibilityFormInput.val(),
_token: token
//Clear list
document.querySelector("#status-update select[name='destinationStopoverId']").innerHTML = "";

let alternativeDestinations = JSON.parse(dataset.trwlAlternativeDestinations);
if (alternativeDestinations) {
document.querySelector('.destination-wrapper').classList.remove('d-none');
for (let destId in alternativeDestinations) {
let dest = alternativeDestinations[destId];
let stopoverId = dest.id;
let stopoverName = dest.name;
let stopoverArrival = dest.arrival_planned;

let stopoverOption = document.createElement("option");
stopoverOption.value = stopoverId;
stopoverOption.text = stopoverArrival + ': ' + stopoverName;
document.querySelector("#status-update select[name='destinationStopoverId']").appendChild(stopoverOption);
}
}).done(function (msg) {
window.location.reload();
});
document.querySelector("#status-update select[name='destinationStopoverId']").value = dataset.trwlDestinationStopover;
} else {
document.querySelector('.destination-wrapper').classList.add('d-none');
}

$("#edit-modal").modal("show");
document.querySelector('#body-length').innerText = document.querySelector('#status-body').value.length;
});
3 changes: 2 additions & 1 deletion resources/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"controller.status.like-deleted": "Like gelöscht.",
"controller.status.like-not-found": "Like nicht gefunden.",
"controller.status.like-ok": "Liked!",
"controller.status.not-permitted": "DAS darfst Du nicht.",
"controller.status.not-permitted": "Das darfst Du nicht.",
"controller.transport.checkin-heading": "Eingecheckt",
"controller.transport.checkin-ok": "Du hast erfolgreich in :lineName eingecheckt!|Du hast erfolgreich in Linie :lineName eingecheckt!",
"controller.transport.no-name-given": "Du musst einen Stationsnamen angeben!",
Expand Down Expand Up @@ -437,6 +437,7 @@
"status.visibility.3.detail": "Nur für dich sichtbar",
"status.visibility.4": "Nur angemeldete Nutzer",
"status.visibility.4.detail": "Nur für angemeldete Nutzer sichtbar",
"status.update.success": "Dein Status wurde aktualisiert.",
"time-format": "HH:mm",
"time-format.with-day": "HH:mm (DD.MM.YYYY)",
"datetime-format": "DD.MM.YYYY HH:mm",
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/de_pfl.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"controller.status.like-deleted": "Gefallt-mer gelescht.",
"controller.status.like-not-found": "Gefallt-mer ned gefunn.",
"controller.status.like-ok": "Gefallt-mer!",
"controller.status.not-permitted": "DES därfsch du ned.",
"controller.status.not-permitted": "Des därfsch du ned.",
"controller.transport.checkin-heading": "Ingecheckt",
"controller.transport.checkin-ok": "Du hasch erfolgreich in :lineName ingecheckt!|Du hasch erfoglreich in Linje :lineName ingecheckt!",
"controller.transport.no-name-given": "Du musch e Stationsname angewwe!",
Expand Down
3 changes: 2 additions & 1 deletion resources/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"controller.status.like-deleted": "Like deleted.",
"controller.status.like-not-found": "Like not found.",
"controller.status.like-ok": "Like created!",
"controller.status.not-permitted": "You 're not permitted to do this.",
"controller.status.not-permitted": "You're not permitted to do this.",
"controller.social.already-connected-error": "This Account is already connected to another user.",
"controller.social.create-error": "There has been an error creating your account.",
"controller.social.delete-never-connected": "Your user does not have a Social Login provider.",
Expand Down Expand Up @@ -413,6 +413,7 @@
"status.visibility.3.detail": "Only visible for you",
"status.visibility.4": "Only logged-in users",
"status.visibility.4.detail": "Only visible for logged-in users",
"status.update.success": "Your Status has been updated successfully.",
"transport_types.bus": "bus",
"transport_types.business": "Business Trip",
"transport_types.businessPlural": "Business Trips",
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"controller.status.like-deleted": "Like verwijdert.",
"controller.status.like-not-found": "Like niet gevonden.",
"controller.status.like-ok": "Liked!",
"controller.status.not-permitted": "DAT mag je niet doen.",
"controller.status.not-permitted": "Dat mag je niet doen.",
"controller.transport.no-name-given": "Je moet een stationsnaam invullen!",
"controller.transport.not-in-stopovers": "De start-id is niet in de tussenstops.",
"controller.transport.also-in-connection": "Ook in deze verbinding zijn:",
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"controller.status.like-deleted": "Like raderats.",
"controller.status.like-not-found": "Like hittades inte.",
"controller.status.like-ok": "Liked!",
"controller.status.not-permitted": "DET får du inte.",
"controller.status.not-permitted": "Det får du inte.",
"controller.transport.checkin-heading": "Checkat in",
"controller.transport.checkin-ok": "Du har lyckats checka in på :lineName!|Du har lyckats checka in på tågförbindelsen :lineName!",
"controller.transport.no-name-given": "Du måste ange ett stationsnamn!",
Expand Down
Loading

0 comments on commit a690025

Please sign in to comment.