package RPS::Import::OrchardPub2;

use strict;

use Data::Dumper;
use lib '/app/tools/common/lib';
use Common::Util qw(normalize_upc normalize_isrc);
use Date::Calc qw(Days_in_Month);

use lib '/app/tools/data_classes/lib';

use lib '/app/tools/rps/lib';
use RPS::File::Sale;
use RPS::Import::ServiceMap;
use RPS::DB::Item::MediaType;
use base 'RPS::Import::MapFaceBase';
use base 'RPS::Import::Importer';

sub _headerIdentifier { ( countryCode => 'Territory' ) }

sub _fieldMap {
    my $self = shift;

    my %fieldMap = (
        14 => {
            dateBegin        => 1,
            serviceID        => 2,
            countryCode      => 3,
            upc              => 5,
            serviceProductID => 4,
            clientProductID  => 6,
            labelName        => 7,
            artistName       => 8,
            albumName        => 9,
            trackName        => 10,
            isrc             => 11,
            trackNum         => 13,
            units            => 14,
            formatType       => 17,
            price            => 20,
            currencyCode     => 24,
        },
        15 => {
            dateBegin        => 1,
            serviceID        => 2,
            countryCode      => 3,
            upc              => 4,
            serviceProductID => 5,
            clientProductID  => 6,
            labelName        => 7,
            artistName       => 8,
            albumName        => 9,
            trackName        => 10,
            isrc             => 11,
            trackNum         => 13,
            units            => 14,
            formatType       => 15,
            price            => 16,
            currencyCode     => 17,
        },
        16 => {
            dateBegin        => 1,     # B
            serviceID        => 2,     # C
            countryCode      => 3,     # D
            upc              => 4,     # E
            serviceProductID => 5,     # F
            clientProductID  => 6,     # G
            labelName        => 8,     # I
            artistName       => 9,     # J
            albumName        => 10,    # K
            trackName        => 11,    # L
            isrc             => 12,    # M
            trackNum         => 14,    # O
            units            => 15,    # P
            formatType       => 18,    # S
            price            => 21,    # V
            currencyCode     => 25,    # Z
        },
        21 => {
            dateBegin       => 'B',
            serviceID       => 'C',
            countryCode     => 'D',
            clientProductID => 'G',
            labelName       => 'I',
            artistName      => 'J',
            albumName       => 'K',
            trackName       => 'L',
            isrc            => 'M',
            trackNum        => 'O',
            units           => 'P',
            formatType      => 'S',
            price           => 'V',
            currencyCode    => 'AA',
        },
    );

    return $fieldMap{ $self->_version() };
}

sub _unverifiedFieldMap {
    my $self = shift;

    my %fieldMap = (
        14 => {
            ringFee => 21,
            pubFee  => 22,
            omsFee  => 23,
        },
        21 => {
            manufacturersUPC => 'F',
            orchardUPC       => 'E',
            ringFee          => 'W',
            cloudFee         => 'X',
            pubFee           => 'Y',
            omsFee           => 'Z',
        },
    );

    return $fieldMap{ $self->_version() };
}

my %formatMap = (
    'AP' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'AS' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'AV' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'CL' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'DA' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'DR' => {
        format_type  => RPS::File::Sale::FORMAT_RINGTONE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'DT' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'DV' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'EQ' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'MT' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'MV' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'NR' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'UN' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'NS' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'NT' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'PS' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'RB' => {
        format_type  => RPS::File::Sale::FORMAT_RINGTONE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'RC' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'RL' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'RE' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'S' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'SB' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'SV' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'TA' => {
        format_type  => RPS::File::Sale::FORMAT_TETHERED,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'TD' => {
        format_type  => RPS::File::Sale::FORMAT_TETHERED,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'UA' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOADUPGRADE,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'UT' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOADUPGRADE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'UV' => {
        format_type  => RPS::File::Sale::FORMAT_DOWNLOADUPGRADE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'VR' => {
        format_type  => RPS::File::Sale::FORMAT_TETHERED,
        product_type => RPS::File::Sale::TYPE_ALBUM,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'VA' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'VS' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'YP' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'CE' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'CR' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'NT' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'TL' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'DB' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'US' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'VU' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'AEA' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'AEV' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'EH' => {
        format_type  => RPS::File::Sale::FORMAT_EPHEMERAL,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'MD' => {
        format_type  => RPS::File::Sale::FORMAT_EPHEMERAL,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'PA' => {
        format_type  => RPS::File::Sale::FORMAT_EPHEMERAL,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'PV' => {
        format_type  => RPS::File::Sale::FORMAT_EPHEMERAL,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'UP' => {
        format_type  => RPS::File::Sale::FORMAT_EPHEMERAL,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'RC' => {
        format_type  => RPS::File::Sale::FORMAT_NON_EPHEMERAL,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'FP' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'FS' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'FA' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'PF' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'DJ' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'KA' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'KS' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'SC' => {
        format_type  => RPS::File::Sale::FORMAT_SYNC,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'SR' => {
        format_type  => RPS::File::Sale::FORMAT_SYNC,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'AC' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'AO' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'SF' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'WS' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'WA' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'RW' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'SL' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'CC' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'TV' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'PP' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'RR' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'MA' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ER' => {
        format_type  => RPS::File::Sale::FORMAT_PERFORMANCE,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ME' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'UQ' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'NQ' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'SA' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'OR' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'OP' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'LP' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'LR' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'MP' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'MR' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'TP' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'TR' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'PX' => {
        format_type  => RPS::File::Sale::FORMAT_STREAM,
        product_type => RPS::File::Sale::TYPE_TRACK,
        media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'YM' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'YA' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'XM' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'XA' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'OC' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'OG' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'YC' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'YG' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'XC' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'XG' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'CT' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'GT' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'PT' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'ST' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'BT' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'TY' => {
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            product_type => RPS::File::Sale::TYPE_TRACK,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
);

sub _getMappings {
    my $self    = shift;
    my $format  = shift;
    my $mapping = $formatMap{$format};
    return $mapping;
}

# Accessor for formatMap
sub get_format_map {
    return \%formatMap;
}

sub countryCode {
    my $self = shift;

    my $name    = $self->_getByFieldName('countryCode');
    my $country = Common::Country->Get($name);
    if ($country) {
        return $country->alpha2();
    } else {
        return $name;
    }
}

sub serviceID {
    my $self    = shift;
    my $service = $self->_getByFieldName('serviceID');

    my $serviceID = $self->getServiceID( lc($service) ) || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $service };

    return $serviceID if ($serviceID);

    return $self->handleError( "Unknown service: $service", RPS::DB::Item::SaleImportError::kErrorService );
}

sub currencyCode {
    my $self = shift;

    my $code = $self->_getByFieldName('currencyCode');

    if ( $code =~ /^(\w{3})/ ) {
        return $1;
    } else {
        return $code;
    }
}

sub trackName {
    my $self = shift;

    my $trackName = $self->_getByFieldName('trackName');

    if ( $trackName !~ /^Full Album$/i ) {
        return $trackName;
    }
}

sub upc {
    my $self = shift;

    my $upc;

    my $manufacturerUPC = ( defined $self->_getByFieldName('manufacturerUPC') ) ? $self->_getByFieldName('manufacturerUPC') : undef;
    my $orchardUPC      = ( defined $self->_getByFieldName('orchardUPC') )      ? $self->_getByFieldName('orchardUPC')      : undef;

    if ( $manufacturerUPC || $orchardUPC ) {
        $upc = ($manufacturerUPC) ? $manufacturerUPC : $orchardUPC;
    } else {
        $upc = $self->_getByFieldName('upc');

        if ( !$upc ) {
            $upc = $self->_getByFieldName('serviceProductID');
        }
    }

    return normalize_upc($upc);
}

sub isrc {
    my $self = shift;
    my $isrc = $self->_getByFieldName('isrc');

    # Let the ISRC through if it looks like an ISRC (e.g., starts with a letter).
    #

    if ( $isrc =~ /^[a-z]/i ) {
        return $isrc;
    }
}

sub units {
    my $self = shift;

    my $units = $self->_getByFieldName('units') || 0;
    $units =~ s/\.0+$//g;    # remove any trailing decimal zeroes
    $units =~ s/,//g;

    my $price = $self->price;

    $units = abs($units);

    if ( $price < 0 ) {
        $units *= -1;
    }

    return $units;
}

sub price {
    my $self = shift;

    my $price = $self->_getByFieldName('price') || 0;
    $price =~ s/\$//g;
    $price =~ s/,//g;

    # If the template doesn't have the ring/cloud/pub/oms fields, then
    # default them to zero.
    #
    my $ringFee  = ( defined $self->_getByFieldName('ringFee') )  ? $self->_getByFieldName('ringFee')  : 0;
    my $cloudFee = ( defined $self->_getByFieldName('cloudFee') ) ? $self->_getByFieldName('cloudFee') : 0;
    my $pubFee   = ( defined $self->_getByFieldName('pubFee') )   ? $self->_getByFieldName('pubFee')   : 0;
    my $omsFee   = ( defined $self->_getByFieldName('omsFee') )   ? $self->_getByFieldName('omsFee')   : 0;

    # Look at the adjusted gross if no revenue reported
    #
    my $adjGross = ( defined $self->_getByFieldName('adjGross') ) ? $self->_getByFieldName('adjGross') : 0;
    $price = $adjGross if ( !defined $price || $price == 0 );

    $ringFee =~ s/\$//g;
    $cloudFee =~ s/\$//g;
    $pubFee =~ s/\$//g;
    $omsFee =~ s/\$//g;

    $ringFee  *= -1 if ( $ringFee < 0 );
    $cloudFee *= -1 if ( $cloudFee < 0 );
    $pubFee   *= -1 if ( $pubFee < 0 );
    $omsFee   *= -1 if ( $omsFee < 0 );

    $price = $price - $ringFee - $cloudFee - $pubFee - $omsFee;

    return $price;
}

sub formatType {
    my $self = shift;

    # RSD-11462
    if ( $self->serviceID == Client::Service::DSP_SOUNDEXCHANGE ) {
        return RPS::File::Sale::FORMAT_NON_EPHEMERAL;
    }

    my $_formatType = uc $self->_getByFieldName('formatType');
    my $formatType = $formatMap{$_formatType}->{format_type};

    if ($formatType) {
        return $formatType;
    } else {
        return $_formatType;
    }
}

sub productType {
    my $self        = shift;
    my $_formatType = uc $self->_getByFieldName('formatType');

    my $productType = $formatMap{$_formatType}->{product_type};

    if ($productType) {
        return $productType;
    } else {
        return $_formatType;
    }
}

sub mediaType {
    my $self        = shift;
    my $_formatType = uc $self->_getByFieldName('formatType');

    my $mediaType = $formatMap{$_formatType}->{media_type};

    if ($mediaType) {
        return $mediaType;
    } else {
        return $_formatType;
    }
}

sub artistName {
    my $self = shift;

    return $self->SUPER::artistName() if $self->_version != 24;

    if ( !$self->isrc ) {
        return $self->_getByFieldName('_artistName');
    } else {
        return $self->_getByFieldName('_trackArtist') || $self->_getByFieldName('_artistName');
    }
}

sub _getDates {
    my $self = shift;
    my $date = $self->_getByFieldName('dateBegin');
    my ( $month, $year );
    my $offset = 0;

    if ( $self->_version == 24 && Common::RSApp::GetClientID() == Client::Client::kBlack17Media ) {
        $date = $self->_getByFieldName('_dateBeginAlt') || '';
    }

    if ( $date =~ m/^(\d+)$/ ) {
        $date = Spreadsheet::ParseExcel::Utility::ExcelFmt( "yyyy-mm-dd", $date );
    }

    if ( $date =~ /^(\d{4})-(\d{1,2})-(\d{1,2})$/ )    # YYYY-MM-DD
    {
        $month = $2;
        $year  = $1;
    } elsif ( $date =~ m/^(\d{4})q([1234]$)/i ) {
        $month  = $2 * 3;
        $year   = $1;
        $offset = 2;
    } elsif ( $date =~ m/Q([1234])(\d\d)/i ) {
        $month  = $1 * 3;
        $year   = $2 + 2000;
        $offset = 2;
    } elsif ( $date =~ m/^(\d{4})m(\d{1,2})$/i ) {
        $month = $2;
        $year  = $1;
    } elsif ( $date =~ m/^(\d{4})-(\d{1,2})-(\d{1,2})$/i ) {
        $month = $2;
        $year  = $1;
    } elsif ( $date =~ m/(\w*) (\d{4})/ ) {
        my %months = (
            Jan => 1,
            Feb => 2,
            Mar => 3,
            Apr => 4,
            May => 5,
            Jun => 6,
            Jul => 7,
            Aug => 8,
            Sep => 9,
            Oct => 10,
            Nov => 11,
            Dec => 12
        );
        ( $month, $year ) = $date =~ m/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w* (\d{4})/i;
        $month = $months{$month};
    } elsif ( $date =~ m/(\w*)-(\d{4})/ ) {
        my %months = (
            Jan => 1,
            Feb => 2,
            Mar => 3,
            Apr => 4,
            May => 5,
            Jun => 6,
            Jul => 7,
            Aug => 8,
            Sep => 9,
            Oct => 10,
            Nov => 11,
            Dec => 12
        );
        ( $month, $year ) = $date =~ m/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w*-(\d{4})/i;
        $month = $months{$month};
    } elsif ( $date =~ m/(\w{3})-(\d{2})/ ) {
        my %months = (
            Jan => 1,
            Feb => 2,
            Mar => 3,
            Apr => 4,
            May => 5,
            Jun => 6,
            Jul => 7,
            Aug => 8,
            Sep => 9,
            Oct => 10,
            Nov => 11,
            Dec => 12
        );
        ( $month, $year ) = $date =~ m/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w*-(\d{2})/i;
        $month = $months{$month};
        $year += 2000;
    }

    return unless ( $year && $month );
    return ( sprintf( "%04d-%02d-01", $year, $month - $offset ),
        sprintf( "%04d-%02d-%02d", $year, $month, Days_in_Month( $year, $month ) ) );
}

sub _mapFaceCompatibleVersions {
    return ( 14, 15, 16, 18, 20, 21, 22, 24, 25, 28 );
}

sub _mapFaceServiceID {
    return ('serviceID');
}

sub _mapFaceCountryCode {
    return ('countryCode');
}

sub _mapFaceProductType {
    return ('formatType');
}

sub _mapFaceFormatType {
    return ('formatType');
}

sub _mapFaceMediaType {
    return ('formatType');
}

###
1;    # Play nicely.
###
