Created
November 25, 2010 17:27
-
-
Save wchristian/715670 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
package TFX::Flight::Conex; | |
use Moose; | |
use MooseX::HasDefaults::RO; | |
use List::Util qw( min reduce ); | |
use lib '../..'; | |
use TFX::Flight::Conex::LegAccessors; | |
use TFX::Flight::Conex::Leg; | |
extends 'TFX::Flight'; | |
has [qw( itinerary half_return )] => ( isa => 'HashRef', required => 1 ); | |
has [qw( | |
operator flight_type flight_sequence min_advance_days flight_tariff flight_kind seat_count special_code | |
price_two_way direction rate1_type rate1_min_age rate1_max_age rate1_price rate2_type rate2_min_age | |
rate2_max_age rate2_price rate3_type rate3_min_age rate3_max_age rate3_price | |
)] => ( isa => 'Any' ); | |
has legs => ( isa => 'ArrayRef', lazy_build => 1 ); | |
sub _build_table_name { "OWF" } | |
sub _build_data_type { "F" } | |
sub _build_version { "3.0" } | |
sub _build_via_codes { | |
my ( $self ) = @_; | |
my ( undef, @additional_legs ) = @{$self->legs}; | |
return if !@additional_legs; | |
my @via_codes = map { $_->depart_code } @additional_legs; | |
return join ',', @via_codes; | |
} | |
sub _build_currency { $_[0]->price->{currencyIsoCode} } | |
sub _build_price_one_way { $_[0]->price->{value} } | |
sub _build_combination_id { $_[0]->air_rule_set->{openJawCombinationGroup}{name} } | |
sub _build_season_surcharge { | |
my ( $self ) = @_; | |
my $tax_list = $self->half_return->{taxQuoteList}[0]{taxList}; | |
my @taxes = values %{$tax_list}; | |
no warnings 'once'; | |
return reduce { $a + $b->{price}{value} } 0, @taxes; | |
} | |
sub _build_duration_rules { | |
my ( $self ) = @_; | |
my @rules = map $self->convert_duration( $_ ), qw( minimumStay maximumStay ); | |
my $sunday_rule = $self->air_rule_set->{minimumStay}{sundayRule}; | |
push @rules, 'SUN' if $sunday_rule and $sunday_rule eq 'true'; | |
return join ',', @rules; | |
} | |
sub _build_flight_class { | |
my ( $self ) = @_; | |
my $class_id = $self->air_rule_set->{cabinClass}{id}; | |
my %classes = ( | |
CAB_ECONOMY => 'Y', | |
CAB_BUSINESS => 'C', | |
); | |
return $classes{$class_id} || die "Unknown class id: $class_id"; | |
} | |
# helpers | |
sub _build_legs { | |
my ( $self ) = @_; | |
my @legs = @{ $self->itinerary->{segmentList} }; | |
@legs = map TFX::Flight::Conex::Leg->new( raw => $_ ), @legs; | |
return \@legs; | |
} | |
sub leg { $_[0]->legs->[$_[1]] || TFX::Flight::Conex::Leg->new( raw => {} ) } | |
sub air_rule_set { $_[0]->half_return->{airRuleSet} } | |
sub price { $_[0]->half_return->{farePassengerTypePriceList}[0]{purchasePrice} } | |
sub convert_duration { | |
my ( $self, $type ) = @_; | |
my $duration = $self->air_rule_set->{$type}; | |
die "duration type missing: '$type'" if !$duration; | |
my $prefix = $self->get_duration_rule_prefix( $type ); | |
$duration->{value} = min( $duration->{value}, 99 ); | |
return $prefix . "99" if $duration->{value} > 3 and $duration->{unit}{id} eq 'STU_MONTHS'; | |
return $prefix . "99" if $duration->{value} >= 1 and $duration->{unit}{id} eq 'STU_YEARS'; | |
return sprintf( "%s%02d", $prefix, $duration->{value} ) if $duration->{unit}{id} eq 'STU_DAYS'; | |
return sprintf( "%s%02d", $prefix, $duration->{value} * 30 ) if $duration->{unit}{id} eq 'STU_MONTHS'; | |
die "unknown duration unit id '$duration->{unit}{id}' with value '$duration->{value}'"; | |
} | |
sub get_duration_rule_prefix { | |
my ( $self, $type ) = @_; | |
return 'A' if $type eq 'minimumStay'; | |
return 'B' if $type eq 'maximumStay'; | |
die "unknown duration type"; | |
} | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
package TFX::Flight; | |
use Moose; | |
use MooseX::HasDefaults::RO; | |
use Class::Load 'load_class'; | |
use lib '..'; | |
use TFX::Sealtix; | |
has [ TFX::Sealtix->get_fields ] => ( isa => 'Any', lazy_build => 1 ); | |
sub build { | |
my ( $class, %args ) = @_; | |
my $source = delete $args{source}; | |
my $engine = "$class\::$source"; | |
load_class( $engine ); | |
return $engine->new( $args{data} ); | |
} | |
sub as_hash { | |
my ( $self ) = @_; | |
my @fields = $self->hash_fields; | |
my %hash = map $self->_get_field_value($_), @fields; | |
return \%hash; | |
} | |
sub hash_fields { | |
my ( $self ) = @_; | |
my @fields = TFX::Sealtix->get_fields; | |
# trim multi leg flight fields if it's a single leg flight | |
@fields = grep { !/^leg\d_/ } @fields if @{ $self->legs } < 2; | |
# trim certain flight fields if it's a multi leg flight | |
@fields = grep { $_ ne 'flight_carrier' and $_ ne 'flight_number' } @fields if @{ $self->legs } > 1; | |
return @fields; | |
} | |
sub _get_field_value { | |
my ( $self, $field ) = @_; | |
return ( $field => $self->$field ) if defined $self->$field; | |
return; | |
} | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
package TFX::Flight::Conex::Leg; | |
use Moose; | |
has raw => ( isa => 'HashRef', is => 'ro' ); | |
sub flight_carrier { $_[0]->raw->{operatingAirline}{code} } | |
sub flight_number { $_[0]->raw->{flightNumber} } | |
sub depart_code { $_[0]->raw->{departure}{code} } | |
sub arrive_code { $_[0]->raw->{destination}{code} } | |
sub depart_date { $_[0]->regex_filter( 'departureDate' ) } | |
sub depart_time { $_[0]->regex_filter( 'departureTimestamp' ) } | |
sub arrive_time { $_[0]->regex_filter( 'arrivalTimestamp' ) } | |
sub regex_filter { | |
my ( $self, $key ) = @_; | |
my $value = $self->raw->{$key}; | |
return if !$value; | |
$value =~ s/^.*T(\d+):(\d+):.*$/$1$2/ if grep { $_ eq $key } qw( departureTimestamp arrivalTimestamp ); | |
$value =~ s:(\d+)-(\d+)-(\d+):$3.$2.$1: if grep { $_ eq $key } qw( departureDate ); | |
return $value; | |
} | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
package TFX::Flight::Conex::LegAccessors; | |
# ABSTRACT: generate and export 21 attribute accessor subs so we don't need to copy-paste | |
use Sub::Exporter -setup => { groups => { default => \'_build_leg_accessors' } }; | |
use Sub::Curry 'curry'; | |
sub _build_leg_accessors { | |
my @legs = qw( 1 2 3 ); | |
my %main_subs = map build_main_accessors( @{$_} ), main_sub_data(); | |
my %leg_subs = map build_accessors_per_leg($_), @legs; | |
return { %main_subs, %leg_subs }; | |
} | |
sub main_sub_data { | |
return ( | |
[ 0, 'flight_carrier' ], | |
[ 0, 'flight_number' ], | |
[ 0, 'depart_code' ], | |
[ -1, 'arrive_code' ], | |
[ 0, 'depart_date' ], | |
[ 0, 'depart_time' ], | |
[ -1, 'arrive_time' ], | |
); | |
} | |
sub build_main_accessors { | |
my ( $id, $field ) = @_; | |
return "_build_$field" => curry( \&accessor_base, $field, $id ); | |
} | |
sub build_accessors_per_leg { | |
my ( $leg ) = @_; | |
my @fields = qw( flight_carrier flight_number depart_code arrive_code depart_date depart_time arrive_time ); | |
return map build_accessors_per_field( $leg, $_ ), @fields; | |
} | |
sub build_accessors_per_field { | |
my ( $leg, $field ) = @_; | |
my $sub = "leg$leg\_$field"; | |
my $id = $leg - 1; | |
my $accessor = curry( \&accessor_base, $field, $id ); | |
return $sub => $accessor; | |
} | |
sub accessor_base { | |
my ( $field, $id, $self ) = @_; | |
my $value = $self->leg( $id )->$field; | |
return $value; | |
} | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment