Commit c0c7b1a5 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Work-in-progress journey editor. Not ready for deployment.

parent beb17acb
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ Dependencies
 * perl >= 5.10
 * Cache::File (part of the Cache module)
 * Crypt::Eksblowfish
 * DateTime
 * DateTime::Format::Strptime
 * DBI
 * DBD::Pg
 * Email::Sender
+125 −5
Original line number Diff line number Diff line
@@ -266,6 +266,37 @@ sub startup {
			);
		}
	);
	$self->attr(
		action_set_sched_time_query => sub {
			my ($self) = @_;

         # TODO (re-)initialize all automatically added journeys with edited = 0
         # and use it as a bit field to precisely indicate which fields have
         # been edited. -> ".. set edited = edited | 1", "... | 2" etc.
         # The action_id check is redundant, but better safe than sorry
			return $self->app->dbh->prepare(
				qq{
					update user_actions
					set sched_time = to_timestamp(?), edited = 1
					where id = ? and action_id = ?
				}
			);
		}
	);
	$self->attr(
		action_set_real_time_query => sub {
			my ($self) = @_;

			# The action_id check is redundant, but better safe than sorry
			return $self->app->dbh->prepare(
				qq{
					update user_actions
					set real_time = to_timestamp(?), edited = 1
					where id = ? and action_id = ?
				}
			);
		}
	);
	$self->attr(
		action_query => sub {
			my ($self) = @_;
@@ -312,7 +343,7 @@ sub startup {
			stations.ds100, stations.name,
			train_type, train_line, train_no, train_id,
			extract(epoch from sched_time), extract(epoch from real_time),
			route, messages
			route, messages, edited
			from user_actions
			left outer join stations on station_id = stations.id
			where user_id = ?
@@ -331,7 +362,7 @@ sub startup {
			stations.ds100, stations.name,
			train_type, train_line, train_no, train_id,
			extract(epoch from sched_time), extract(epoch from real_time),
			route, messages
			route, messages, edited
			from user_actions
			left outer join stations on station_id = stations.id
			where user_id = ?
@@ -354,7 +385,7 @@ sub startup {
			stations.ds100, stations.name,
			train_type, train_line, train_no, train_id,
			extract(epoch from sched_time), extract(epoch from real_time),
			route, messages
			route, messages, edited
			from user_actions
			left outer join stations on station_id = stations.id
			where user_id = ?
@@ -375,7 +406,7 @@ sub startup {
			stations.ds100, stations.name,
			train_type, train_line, train_no, train_id,
			extract(epoch from sched_time), extract(epoch from real_time),
			route, messages
			route, messages, edited
			from user_actions
			left outer join stations on station_id = stations.id
			where user_id = ?
@@ -808,6 +839,77 @@ qq{select * from pending_mails where email = ? and num_tries > 1;}
		}
	);

	$self->helper(
		'update_journey_part' => sub {
			my ( $self, $checkin_id, $checkout_id, $key, $value ) = @_;
			my ( $query, $id, $action_type );

			if ( $key eq 'sched_departure' ) {
				$query       = $self->app->action_set_sched_time_query;
				$id          = $checkin_id;
				$action_type = $self->app->action_type->{checkin};
			}
			elsif ( $key eq 'rt_departure' ) {
				$query       = $self->app->action_set_real_time_query;
				$id          = $checkin_id;
				$action_type = $self->app->action_type->{checkin};
			}
			elsif ( $key eq 'sched_arrival' ) {
				$query       = $self->app->action_set_sched_time_query;
				$id          = $checkout_id;
				$action_type = $self->app->action_type->{checkout};
			}
			elsif ( $key eq 'rt_arrival' ) {
				$query       = $self->app->action_set_real_time_query;
				$id          = $checkout_id;
				$action_type = $self->app->action_type->{checkout};
			}
			else {
				$self->app->log->error(
					"update_journey_part(id = $id): Invalid key $key");
				return 'Internal Error';
			}

			my $success = $query->execute( $value, $id, $action_type );
			if ($success) {
				if ( $query->rows == 1 ) {
					return undef;
				}
				return 'UPDATE failed: did not match any journey part';
			}
			my $err = $query->errstr;
			$self->app->log->error(
				"update_journey_part($id): UPDATE failed: $err");
			return 'UPDATE failed: ' . $err;
		}
	);

	$self->helper(
		'journey_sanity_check' => sub {
			my ( $self, $journey ) = @_;

			if ( $journey->{sched_duration} and $journey->{sched_duration} < 0 )
			{
				return 'Die geplante Dauer dieser Zugfahrt ist negativ';
			}
			if ( $journey->{rt_duration} and $journey->{rt_duration} < 0 ) {
				return 'Die Dauer dieser Zugfahrt ist negativ';
			}
			if (    $journey->{sched_duration}
				and $journey->{sched_duration} > 60 * 60 * 24 )
			{
				return 'Die Zugfahrt ist länger als 24 Stunden';
			}
			if (    $journey->{rt_duration}
				and $journey->{rt_duration} > 60 * 60 * 24 )
			{
				return 'Die Zugfahrt ist länger als 24 Stunden';
			}

			return undef;
		}
	);

	$self->helper(
		'get_station_id' => sub {
			my ( $self, %opt ) = @_;
@@ -1161,7 +1263,7 @@ qq{select * from pending_mails where email = ? and num_tries > 1;}
					$ds100,        $name,        $train_type,
					$train_line,   $train_no,    $train_id,
					$raw_sched_ts, $raw_real_ts, $raw_route,
					$raw_messages
					$raw_messages, $edited
				) = @row;

				if ( $action == $match_actions[0]
@@ -1185,6 +1287,7 @@ qq{select * from pending_mails where email = ? and num_tries > 1;}
							? [ split( qr{[|]}, $raw_route ) ]
							: undef,
							completed => 0,
							edited    => $edited // 0,
						}
					);
				}
@@ -1208,6 +1311,7 @@ qq{select * from pending_mails where email = ? and num_tries > 1;}
					$ref->{no}       //= $train_no;
					$ref->{messages} //= [ split( qr{[|]}, $raw_messages ) ];
					$ref->{route}    //= [ split( qr{[|]}, $raw_route ) ];
					$ref->{edited} += $edited;

					if ( $opt{verbose} ) {
						my @parsed_messages;
@@ -1272,6 +1376,22 @@ qq{select * from pending_mails where email = ? and num_tries > 1;}
		}
	);

	$self->helper(
		'get_journey' => sub {
			my ( $self, %opt ) = @_;

			my @journeys = $self->get_user_travels(%opt);
			if (   @journeys == 0
				or not $journeys[0]{completed}
				or $journeys[0]{ids}[1] != $opt{checkout_id} )
			{
				return undef;
			}

			return $journeys[0];
		}
	);

	$self->helper(
		'get_user_status' => sub {
			my ( $self, $uid ) = @_;
+59 −8
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ package Travelynx::Controller::Traveling;
use Mojo::Base 'Mojolicious::Controller';

use DateTime;
use DateTime::Format::Strptime;
use Travel::Status::DE::IRIS::Stations;

sub homepage {
@@ -427,14 +428,12 @@ sub edit_journey {
		return;
	}

	my @journeys = $self->get_user_travels(
	my $journey = $self->get_journey(
		uid         => $uid,
		checkout_id => $checkout_id,
		checkout_id => $checkout_id
	);
	if (   @journeys == 0
		or not $journeys[0]{completed}
		or $journeys[0]{ids}[1] != $checkout_id )
	{

	if ( not $journey ) {
		$self->render(
			'edit_journey',
			error   => 'notfound',
@@ -443,7 +442,59 @@ sub edit_journey {
		return;
	}

	my $journey = $journeys[0];
	my $error = undef;

	if ( $self->param('action') and $self->param('action') eq 'cancel' ) {
		$self->redirect_to("/journey/${uid}-${checkout_id}");
		return;
	}

	if ( $self->param('action') and $self->param('action') eq 'save' ) {
		my $parser = DateTime::Format::Strptime->new(
			pattern   => '%d.%m.%Y %H:%M',
			locale    => 'de_DE',
			time_zone => 'Europe/Berlin'
		);

		$self->app->dbh->begin_work;

		for my $key (qw(sched_departure rt_departure sched_arrival rt_arrival))
		{
			my $datetime = $parser->parse_datetime( $self->param($key) );
			if ( $datetime and $datetime->epoch ne $journey->{$key}->epoch ) {
				$error = $self->update_journey_part(
					$journey->{ids}[0],
					$journey->{ids}[1],
					$key, $datetime->epoch
				);
				if ($error) {
					last;
				}
			}
		}

		if ($error) {
			$self->app->dbh->rollback;
		}
		else {
			$journey = $self->get_journey(
				uid         => $uid,
				checkout_id => $checkout_id,
				verbose     => 1
			);
			$error = $self->journey_sanity_check($journey);
			if ($error) {
				$self->app->dbh->rollback;
			}
			else {
				$self->invalidate_stats_cache( $journey->{checkout} );
				$self->app->dbh->commit;
				$self->redirect_to("/journey/${uid}-${checkout_id}");
				return;
			}
		}

	}

	for my $key (qw(sched_departure rt_departure sched_arrival rt_arrival)) {
		if ( $journey->{$key} and $journey->{$key}->epoch ) {
@@ -458,7 +509,7 @@ sub edit_journey {

	$self->render(
		'edit_journey',
		error   => undef,
		error   => $error,
		journey => $journey
	);
}
+10 −9
Original line number Diff line number Diff line
<h1>Zugfahrt bearbeiten</h1>
% if ($error and $error eq 'notfound') {
	<div class="row">
		<div class="col s12">
@@ -25,6 +26,7 @@
	% }
	%= form_for '/journey/edit' => (method => 'POST') => begin
		%= csrf_field
		%= hidden_field 'journey_id' => param('journey_id')
		<div class="row">
			<div class="col s12">
				<p>
@@ -35,6 +37,10 @@
					am
					<b><%= $journey->{sched_departure}->strftime('%d.%m.%Y') %></b>
				</p>
				<p>
					Nach einer Änderung können die ursprünglich eingetragenen
					Zeiten nicht mehr wiederhergestellt werden.
				</p>
				<table class="striped">
					<tr>
						<th scope="row">Zug</th>
@@ -69,17 +75,14 @@
							%= text_field 'rt_arrival', id => 'real_arrival', class => 'validate', pattern => '[0-9][0-9]?[.][0-9][0-9]?[.][0-9][0-9][0-9][0-9] +[0-9][0-9]:[0-9][0-9]'
						</td>
					</tr>
					<tr>
						<th scope="row">Route</th>
						<td>
							%= text_area 'route', id => 'route', cols => 40, rows => 20
						</td>
					</tr>
				</table>
			</div>
		</div>
		<div class="row">
			<div class="col s3 m3 l3">
			<div class="col s6 m6 l6 center-align">
				<button class="btn waves-effect waves-light" type="submit" name="action" value="cancel">
					Abbrechen
				</button>
			</div>
			<div class="col s6 m6 l6 center-align">
				<button class="btn waves-effect waves-light" type="submit" name="action" value="save">
@@ -87,8 +90,6 @@
					<i class="material-icons right">send</i>
				</button>
			</div>
			<div class="col s3 m3 l3">
			</div>
		</div>
	%= end
% }
+4 −1
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@
				am
				<b><%= $journey->{sched_departure}->strftime('%d.%m.%Y') %></b>
			</p>
			% if ($journey->{edited}) {
				<p>Die Ankunfts- und Abfahrtsdaten wurden nachträglich bearbeitet.</p>
			% }
			<table class="striped">
				<tr>
					<th scope="row">Zug</th>
@@ -141,7 +144,7 @@
		<div class="col s6 m6 l6 center-align">
			%= form_for '/journey/edit' => (method => 'POST') => begin
				%= hidden_field 'journey_id' => param('journey_id')
				<button class="btn waves-effect waves-light" type="submit" name="action" value="edit" disabled="disabled">
				<button class="btn waves-effect waves-light" type="submit" name="action" value="edit">
					Bearbeiten
				</button>
			%= end