support logging of cancelled journeys
This commit is contained in:
parent
e24f895303
commit
01df965d66
7 changed files with 130 additions and 23 deletions
84
index.pl
84
index.pl
|
@ -33,11 +33,13 @@ my $cache_iris_rt = Cache::File->new(
|
||||||
my $dbname = $ENV{TRAVELYNX_DB_FILE} // 'travelynx.sqlite';
|
my $dbname = $ENV{TRAVELYNX_DB_FILE} // 'travelynx.sqlite';
|
||||||
|
|
||||||
my %action_type = (
|
my %action_type = (
|
||||||
checkin => 1,
|
checkin => 1,
|
||||||
checkout => 2,
|
checkout => 2,
|
||||||
undo => 3,
|
undo => 3,
|
||||||
|
cancelled_from => 4,
|
||||||
|
cancelled_to => 5,
|
||||||
);
|
);
|
||||||
my @action_types = (qw(checkin checkout undo));
|
my @action_types = (qw(checkin checkout undo cancelled_from cancelled_to));
|
||||||
my %token_type = (
|
my %token_type = (
|
||||||
status => 1,
|
status => 1,
|
||||||
history => 2,
|
history => 2,
|
||||||
|
@ -476,7 +478,9 @@ sub get_station {
|
||||||
}
|
}
|
||||||
|
|
||||||
helper 'checkin' => sub {
|
helper 'checkin' => sub {
|
||||||
my ( $self, $station, $train_id ) = @_;
|
my ( $self, $station, $train_id, $action_id ) = @_;
|
||||||
|
|
||||||
|
$action_id //= $action_type{checkin};
|
||||||
|
|
||||||
my $status = get_departures($station);
|
my $status = get_departures($station);
|
||||||
if ( $status->{errstr} ) {
|
if ( $status->{errstr} ) {
|
||||||
|
@ -504,10 +508,17 @@ helper 'checkin' => sub {
|
||||||
# XXX same workaround: We can't checkin immediately after checkout.
|
# XXX same workaround: We can't checkin immediately after checkout.
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
elsif ( $user->{cancelled} ) {
|
||||||
|
|
||||||
|
# Same
|
||||||
|
sleep(1);
|
||||||
|
$self->cancelled_to($station);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
my $success = $self->app->action_query->execute(
|
my $success = $self->app->action_query->execute(
|
||||||
$self->current_user->{id},
|
$self->current_user->{id},
|
||||||
$action_type{checkin},
|
$action_id,
|
||||||
$self->get_station_id(
|
$self->get_station_id(
|
||||||
ds100 => $status->{station_ds100},
|
ds100 => $status->{station_ds100},
|
||||||
name => $status->{station_name}
|
name => $status->{station_name}
|
||||||
|
@ -563,13 +574,15 @@ helper 'undo' => sub {
|
||||||
};
|
};
|
||||||
|
|
||||||
helper 'checkout' => sub {
|
helper 'checkout' => sub {
|
||||||
my ( $self, $station, $force ) = @_;
|
my ( $self, $station, $force, $action_id ) = @_;
|
||||||
|
|
||||||
|
$action_id //= $action_type{checkout};
|
||||||
|
|
||||||
my $status = get_departures( $station, 180 );
|
my $status = get_departures( $station, 180 );
|
||||||
my $user = $self->get_user_status;
|
my $user = $self->get_user_status;
|
||||||
my $train_id = $user->{train_id};
|
my $train_id = $user->{train_id};
|
||||||
|
|
||||||
if ( not $user->{checked_in} ) {
|
if ( not $user->{checked_in} and not $user->{cancelled} ) {
|
||||||
return 'You are not checked into any train';
|
return 'You are not checked into any train';
|
||||||
}
|
}
|
||||||
if ( $status->{errstr} and not $force ) {
|
if ( $status->{errstr} and not $force ) {
|
||||||
|
@ -582,7 +595,7 @@ helper 'checkout' => sub {
|
||||||
if ($force) {
|
if ($force) {
|
||||||
my $success = $self->app->action_query->execute(
|
my $success = $self->app->action_query->execute(
|
||||||
$self->current_user->{id},
|
$self->current_user->{id},
|
||||||
$action_type{checkout},
|
$action_id,
|
||||||
$self->get_station_id(
|
$self->get_station_id(
|
||||||
ds100 => $status->{station_ds100},
|
ds100 => $status->{station_ds100},
|
||||||
name => $status->{station_name}
|
name => $status->{station_name}
|
||||||
|
@ -892,6 +905,7 @@ helper 'get_user_status' => sub {
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
checked_in => ( $cols[0] == $action_type{checkin} ),
|
checked_in => ( $cols[0] == $action_type{checkin} ),
|
||||||
|
cancelled => ( $cols[0] == $action_type{cancelled_from} ),
|
||||||
timestamp => $action_ts,
|
timestamp => $action_ts,
|
||||||
timestamp_delta => $now->epoch - $action_ts->epoch,
|
timestamp_delta => $now->epoch - $action_ts->epoch,
|
||||||
sched_ts => $sched_ts,
|
sched_ts => $sched_ts,
|
||||||
|
@ -1070,8 +1084,11 @@ get '/api/v0/:action/:token' => sub {
|
||||||
$self->render(
|
$self->render(
|
||||||
json => {
|
json => {
|
||||||
deprecated => \0,
|
deprecated => \0,
|
||||||
checked_in => $status->{checked_in} ? \1 : \0,
|
checked_in => (
|
||||||
station => {
|
$status->{checked_in}
|
||||||
|
or $status->{cancelled}
|
||||||
|
) ? \1 : \0,
|
||||||
|
station => {
|
||||||
ds100 => $status->{station_ds100},
|
ds100 => $status->{station_ds100},
|
||||||
name => $status->{station_name},
|
name => $status->{station_name},
|
||||||
uic => $station_eva,
|
uic => $station_eva,
|
||||||
|
@ -1302,7 +1319,7 @@ post '/action' => sub {
|
||||||
if ( $params->{action} eq 'checkin' ) {
|
if ( $params->{action} eq 'checkin' ) {
|
||||||
|
|
||||||
my ( $train, $error )
|
my ( $train, $error )
|
||||||
= $self->checkin( $params->{station}, $params->{train}, );
|
= $self->checkin( $params->{station}, $params->{train} );
|
||||||
|
|
||||||
if ($error) {
|
if ($error) {
|
||||||
$self->render(
|
$self->render(
|
||||||
|
@ -1321,7 +1338,7 @@ post '/action' => sub {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( $params->{action} eq 'checkout' ) {
|
elsif ( $params->{action} eq 'checkout' ) {
|
||||||
my $error = $self->checkout( $params->{station}, $params->{force}, );
|
my $error = $self->checkout( $params->{station}, $params->{force} );
|
||||||
|
|
||||||
if ($error) {
|
if ($error) {
|
||||||
$self->render(
|
$self->render(
|
||||||
|
@ -1357,6 +1374,47 @@ post '/action' => sub {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
elsif ( $params->{action} eq 'cancelled_from' ) {
|
||||||
|
my ( undef, $error )
|
||||||
|
= $self->checkin( $params->{station}, $params->{train},
|
||||||
|
$action_type{cancelled_from} );
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
$self->render(
|
||||||
|
json => {
|
||||||
|
success => 0,
|
||||||
|
error => $error,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->render(
|
||||||
|
json => {
|
||||||
|
success => 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $params->{action} eq 'cancelled_to' ) {
|
||||||
|
my $error = $self->checkout( $params->{station}, 1,
|
||||||
|
$action_type{cancelled_to} );
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
$self->render(
|
||||||
|
json => {
|
||||||
|
success => 0,
|
||||||
|
error => $error,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->render(
|
||||||
|
json => {
|
||||||
|
success => 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
$self->render(
|
$self->render(
|
||||||
json => {
|
json => {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
.action-checkin,
|
.action-checkin,
|
||||||
.action-checkout,
|
.action-checkout,
|
||||||
.action-undo {
|
.action-undo,
|
||||||
|
.action-cancelled-from,
|
||||||
|
.action-cancelled-to {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,24 @@ $(document).ready(function() {
|
||||||
var req = {
|
var req = {
|
||||||
action: 'undo',
|
action: 'undo',
|
||||||
};
|
};
|
||||||
tvly_run(link, req, window.location.href);
|
tvly_run(link, req, '/');
|
||||||
|
});
|
||||||
|
$('.action-cancelled-from').click(function() {
|
||||||
|
var link = $(this);
|
||||||
|
var req = {
|
||||||
|
action: 'cancelled_from',
|
||||||
|
station: link.data('station'),
|
||||||
|
train: link.data('train'),
|
||||||
|
};
|
||||||
|
tvly_run(link, req, '/');
|
||||||
|
});
|
||||||
|
$('.action-cancelled-to').click(function() {
|
||||||
|
var link = $(this);
|
||||||
|
var req = {
|
||||||
|
action: 'cancelled_to',
|
||||||
|
station: link.data('station'),
|
||||||
|
force: true,
|
||||||
|
};
|
||||||
|
tvly_run(link, req, '/');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
2
public/static/js/travelynx-actions.min.js
vendored
2
public/static/js/travelynx-actions.min.js
vendored
|
@ -1 +1 @@
|
||||||
function tvly_run(n,t,i,a){var c='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');n.hide(),n.after(o),$.post("/action",t,function(t){t.success?$(location).attr("href",i):(M.toast({html:c+" "+t.error}),o.remove(),a&&a(),n.append(" "+c),n.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),n={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,n,"/s/"+n.station,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){tvly_run($(this),{action:"undo"},window.location.href)})});
|
function tvly_run(n,t,a,c){var i='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');n.hide(),n.after(o),$.post("/action",t,function(t){t.success?$(location).attr("href",a):(M.toast({html:i+" "+t.error}),o.remove(),c&&c(),n.append(" "+i),n.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),n={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,n,"/s/"+n.station,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){tvly_run($(this),{action:"undo"},"/")}),$(".action-cancelled-from").click(function(){var t=$(this);tvly_run(t,{action:"cancelled_from",station:t.data("station"),train:t.data("train")},"/")}),$(".action-cancelled-to").click(function(){var t=$(this);tvly_run(t,{action:"cancelled_to",station:t.data("station"),force:!0},"/")})});
|
||||||
|
|
|
@ -52,22 +52,24 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
% for my $result (@{$results}) {
|
% for my $result (@{$results}) {
|
||||||
% my $class = "";
|
% my $td_class = '';
|
||||||
|
% my $link_class = 'action-checkin';
|
||||||
% if ($result->departure_is_cancelled) {
|
% if ($result->departure_is_cancelled) {
|
||||||
% $class = "cancelled";
|
% $td_class = "cancelled";
|
||||||
|
% $link_class = 'action-cancelled-from';
|
||||||
% }
|
% }
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a class="action-checkin" data-station="<%= $ds100 %>" data-train="<%= $result->train_id %>">
|
<a class="<%= $link_class %>" data-station="<%= $ds100 %>" data-train="<%= $result->train_id %>">
|
||||||
<%= $result->line %>
|
<%= $result->line %>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="<%= $class %>">
|
<td class="<%= $td_class %>">
|
||||||
<a class="action-checkin" data-station="<%= $ds100 %>" data-train="<%= $result->train_id %>">
|
<a class="<%= $link_class %>" data-station="<%= $ds100 %>" data-train="<%= $result->train_id %>">
|
||||||
<%= $result->destination %>
|
<%= $result->destination %>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="<%= $class %>"><%= $result->departure->strftime('%H:%M') %>
|
<td class="<%= $td_class %>"><%= $result->departure->strftime('%H:%M') %>
|
||||||
% if ($result->departure_delay) {
|
% if ($result->departure_delay) {
|
||||||
(+<%= $result->departure_delay %>)
|
(+<%= $result->departure_delay %>)
|
||||||
% }
|
% }
|
||||||
|
|
|
@ -37,6 +37,33 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
% }
|
% }
|
||||||
|
% elsif ($status->{cancelled}) {
|
||||||
|
<div class="card yellow lighten-4">
|
||||||
|
<div class="card-content">
|
||||||
|
<span class="card-title">Zugausfall dokumentieren</span>
|
||||||
|
<p>Prinzipiell wärest du nun eingecheckt in
|
||||||
|
<%= $status->{train_type} %> <%= $status->{train_no} %>
|
||||||
|
ab <%= $status->{station_name} %>, doch dieser Zug fällt aus.
|
||||||
|
% if ($status->{timestamp_delta} < 3600) {
|
||||||
|
<a class="action-undo"><i class="material-icons">undo</i> Checkinversuch rückgängig</a>
|
||||||
|
% }
|
||||||
|
</p>
|
||||||
|
<p>Falls du den Zugausfall z.B. für ein Fahrgastrechteformular
|
||||||
|
dokumentieren möchtest, wähle bitte jetzt deine geplante
|
||||||
|
Zielstation aus. Achtung: Momentan wird dabei keine
|
||||||
|
Soll-Ankunftszeit gespeichert, das zu beheben steht auf
|
||||||
|
der Todoliste.</p>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
% my $is_after = 0;
|
||||||
|
% for my $station (@{$status->{route_after}}) {
|
||||||
|
<tr><td><a class="action-cancelled-to" data-station="<%= $station %>"><%= $station %></a></td></tr>
|
||||||
|
% }
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
% }
|
||||||
% else {
|
% else {
|
||||||
<div class="card grey darken-4">
|
<div class="card grey darken-4">
|
||||||
<div class="card-content white-text">
|
<div class="card-content white-text">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="theme-color" content="#673ab7">
|
<meta name="theme-color" content="#673ab7">
|
||||||
% my $av = 'v3'; # asset version
|
% my $av = 'v4'; # asset version
|
||||||
%= stylesheet "/static/${av}/css/materialize.min.css"
|
%= stylesheet "/static/${av}/css/materialize.min.css"
|
||||||
%= stylesheet "/static/${av}/css/material-icons.css"
|
%= stylesheet "/static/${av}/css/material-icons.css"
|
||||||
%= stylesheet "/static/${av}/css/local.css"
|
%= stylesheet "/static/${av}/css/local.css"
|
||||||
|
|
Loading…
Reference in a new issue