package RPS::Import::ADA::v14;
#
# This importer is similar to v12.pm.  The difference is that the
# international digital sales tab is slightly different in this
# version (the domestic sales tab, however, is the same).
#
use strict;


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

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

use lib '/app/tools/rps/lib';
use RPS::File::Sale;
use RPS::Import::ServiceMap;

use base 'RPS::Import::MapFaceBase';
use base 'RPS::Import::ADA::ADACommon';

sub _headerIdentifier { ( units => qr/UNITS$/ ) }

sub _validateFieldMap {}

sub _fieldMap {
    
    my $self = shift;
    
    my $sheetName = $self->_normalizeSheetName( lc $self->{sheetname} );
    
    my %fieldMaps = (
        'domestic' => {
            label           => 28, # AC 
            serviceID       => 2,  # C
            dateBegin       => 3,  # D
            dateEnd         => 4,  # E
            productType     => 17, # R
            formatType      => 41, # AP
            artistName      => 7,  # H
            upc             => 20, # U
            albumName       => 22, # W
            isrc            => 18, # S
            trackName       => 9,  # J
            units           => 10, # K  
            price           => 15, # P
            mediaType       => 17, # R                                
        },
        'international' => {
            label           => 0,  # A 
            serviceID       => 5,  # F
            countryCode     => 7,  # H

            artistName      => 1,  # B
            albumName       => 2,  # C
            trackName       => 2,  # C

            isrc            => 3,  # D
            upc             => 3,  # D

            units           => 12, # M
            price           => 13, # N
        },        
    );
            
    if ($fieldMaps{$sheetName}) {
        return $fieldMaps{$sheetName};
    }
}

sub _unverifiedFieldMap {
    
    my $self = shift;
    
    my $sheetName = $self->_normalizeSheetName( lc $self->{sheetname} );
    
    my %fieldMaps = (
        'domestic' => {
            mediaCode       => 41, # AP
            streamFlag      => 44, # AS                                 
        },
        'international' => {
            deliveryType    => 9,  # J
            deliveryFormat  => 10, # K
        },        
    );
            
    if ($fieldMaps{$sheetName}) {
        return $fieldMaps{$sheetName};
    }
}

my %mediaCodeMap = (
   'DRMUPGR' => {
      format_type  => RPS::File::Sale::FORMAT_DOWNLOADUPGRADE,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'DUALDIST' => {
      format_type  => RPS::File::Sale::FORMAT_DUALDOWNLOAD,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'PERMDWNL' => {
      format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'PERMVDLD' => {
      format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
   },   
   'SUBAICLD' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'SUBASONE' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'SUBASPPE' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
   },
   'SUBVICLD' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
   },
   'SUBVOLYR' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },   
   'SUBVSONE' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
   },
   'SUBVSPPE' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
   },
   'UGMV' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
   },
   'UGRWRMST' => {
      format_type  => RPS::File::Sale::FORMAT_RINGTONE,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'UGV' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
   },   
   'WRMST' => {
      format_type  => RPS::File::Sale::FORMAT_RINGTONE,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'WRRNGBK' => {
      format_type  => RPS::File::Sale::FORMAT_RINGTONE,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },
   'WRSTREAM' => {
      format_type  => RPS::File::Sale::FORMAT_STREAM,
      media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
   },         
);


# International delivery format mappings
#
# $deliveryFormatMap{$deliveryFormat}{$deliveryType}
#
my %deliveryFormatMap = (
    'emastertone' => {
        'download' => {
            product_type => RPS::File::Sale::TYPE_ALBUM,
            format_type  => RPS::File::Sale::FORMAT_RINGTONE,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
        'wireless' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_RINGTONE,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
    },         
    'emdalbum' => {
        'download' => {
            product_type => RPS::File::Sale::TYPE_ALBUM,
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
        'downloads' => {
            product_type => RPS::File::Sale::TYPE_ALBUM,
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
    },         
    'emdalbumstreaming' => {
        'stream' => {
            product_type => RPS::File::Sale::TYPE_ALBUM,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
        'streaming' => {
            product_type => RPS::File::Sale::TYPE_ALBUM,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
    },         
    'emdalbumstreamingstreamingstreaming' => {
        'streaming' => {
            product_type => RPS::File::Sale::TYPE_ALBUM,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
    },         
    'emdtrack' => {
        'download' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
        'downloads' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
    },         
    'emdtrackstreaming' => {
        'stream' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
        'streaming' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
    },         
    'eringback' => {
        'download' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_RINGTONE,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
        'wireless' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_RINGTONE,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
    },         
    'evd' => {
        'download' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },         
        'downloads' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },         
    },         
    'evdstreaming' => {
        'stream' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },         
        'streaming' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },         
    },         
    'mobile' => {
        'download' => { # FB2929
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'stream' => { # FB2929
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'otherdig' => {
        'download' => { # FB2929
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'stream' => { # FB2929
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'stream' => {
        'emdtrackstreaming' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },                
    },      
    'unknown' => {
        'download' => {
            product_type => RPS::File::Sale::TYPE_TRACK,  # only if ISRC present, album otherwise
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'usergenmastertone' => {
        'wireless' => {
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'web' => {
        'download' => { # FB2929
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'stream' => { # FB2929
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
    'wireless' => {
        'download' => { # FB2929
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_DOWNLOAD,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'stream' => { # FB2929
            product_type => RPS::File::Sale::TYPE_TRACK,
            format_type  => RPS::File::Sale::FORMAT_STREAM,
            media_type   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
    },
);

# Doing this so that version that inherit from this one can pull stuff out of the hash.
sub _getMediaType {
    my $self = shift;
    my %args = @_;
    
    my $deliveryType   = $args{deliveryType};
    my $deliveryFormat = $args{deliveryFormat}; 
    return $deliveryFormatMap{ $deliveryFormat }{ $deliveryType }{ media_type };  
}

sub currencyCode { 'USD' }

sub _preProcess {
    my $self = shift;
    my %args = @_;

    Log->info( "Starting _preProcess" );
    $self->SUPER::_preProcess(%args);

    my $fileName = $args{file}->OrigFileName();
    my ($dateBegin, $dateEnd) = $self->_getDatesFromFileName($fileName);
    $self->{_fileDateBegin} = $dateBegin;
    $self->{_fileDateEnd}   = $dateEnd;
}

sub _getDateBegin {
    my $self = shift;

    if (defined $self->_getByFieldName( 'dateBegin' )) {
        my $saleDateBegin = _normalizeDate($self->_getByFieldName( 'dateBegin' ));
        my ($dateBegin, $dateEnd) = $self->_getDates(date_begin => $saleDateBegin);  
        return $dateBegin;      
    } else {
        return $self->{_fileDateBegin};
    }
}

sub _getDateEnd {
    my $self = shift;

    if (defined $self->_getByFieldName( 'dateBegin' )) {
        my $saleDateBegin = _normalizeDate($self->_getByFieldName( 'dateBegin' ));
        my ($dateBegin, $dateEnd) = $self->_getDates(date_begin => $saleDateBegin);  
        return $dateEnd;      
    } else {
        return $self->{_fileDateEnd};
    }
}
        
sub countryCode {
    my $self = shift;

    if (defined $self->_getByFieldName( 'countryCode' )) {
        my $name = $self->_getByFieldName( 'countryCode' );
		return $name;        
    } else {
        return 'US';   
    }
}

sub formatType {
    my $self = shift;
    my $formatType;
    
    if (defined $self->_getByFieldName( 'mediaCode' )) {
        my $mediaCode = $self->_getByFieldName( 'mediaCode' );
        if (!$mediaCode)  
        {
            return $self->handleError("Media code missing", RPS::DB::Item::SaleImportError::kErrorNonqualifying);
        }            
        
        $formatType  = $mediaCodeMap{ uc $mediaCode }->{ format_type };
        if ($formatType) {
		    return $formatType;        
		} else {
            return $self->handleError("Unknown mediaCode: $mediaCode", RPS::DB::Item::SaleImportError::kErrorFormatType);
		}
    } else {        
        my $deliveryType   = lc $self->_getByFieldName( 'deliveryType' );        
        if (!$deliveryType)  
        {
            return $self->handleError("Delivery type missing", RPS::DB::Item::SaleImportError::kErrorNonqualifying);
        }        
        
        my $deliveryFormat = lc $self->_getByFieldName( 'deliveryFormat' ); 
        if (!$deliveryFormat)  
        {
            return $self->handleError("Delivery format missing", RPS::DB::Item::SaleImportError::kErrorNonqualifying);
        }         
        
        
        $formatType  = $deliveryFormatMap{ $deliveryFormat }{ $deliveryType }{ format_type };  
        if ($formatType) {
		    return $formatType;        
		} else {
            return $self->handleError("Unknown deliveryType($deliveryType) deliveryFormat($deliveryFormat)", RPS::DB::Item::SaleImportError::kErrorFormatType);
		}        
    }
}

sub mediaType {
    my $self = shift;
    my $mediaType;
    
    if (defined $self->_getByFieldName( 'mediaCode' )) {
        my $mediaCode = $self->_getByFieldName( 'mediaCode' );
        if (!$mediaCode)  
        {
            return $self->handleError("Media code missing", RPS::DB::Item::SaleImportError::kErrorNonqualifying);
        }           
                
        $mediaType  = $mediaCodeMap{ uc $mediaCode }->{ media_type };
        if ($mediaType) {
		    return $mediaType;        
		} else {
            return $self->handleError("Unknown mediaCode: $mediaCode", RPS::DB::Item::SaleImportError::kErrorMediaType);
		}
    } else {
        my $deliveryType   = lc $self->_getByFieldName( 'deliveryType' );        
        if (!$deliveryType)  
        {
            return $self->handleError("Delivery type missing", RPS::DB::Item::SaleImportError::kErrorNonqualifying);
        }        
        
        my $deliveryFormat = lc $self->_getByFieldName( 'deliveryFormat' ); 
        if (!$deliveryFormat)  
        {
            return $self->handleError("Delivery format missing", RPS::DB::Item::SaleImportError::kErrorNonqualifying);
        }    
        
        $mediaType  = $deliveryFormatMap{ $deliveryFormat }{ $deliveryType }{ media_type };  
        if ($mediaType) {
		    return $mediaType;        
		} else {
            return $self->handleError("Unknown deliveryType($deliveryType) deliveryFormat($deliveryFormat)", RPS::DB::Item::SaleImportError::kErrorMediaType);
		}        
    }
}
      
sub productType {
    my $self = shift;
    my $productType;
    
    if (defined $self->_getByFieldName( 'mediaCode' )) {
        $productType = $self->_getByFieldName( 'productType' );

        if (!$productType)  
        {
            return $self->handleError("Product type missing", RPS::DB::Item::SaleImportError::kErrorNonqualifying);
        }
        elsif( $productType eq 'D' || $productType eq 'P' || $productType eq 'T' || $productType eq 'S' || $productType eq 'DL' )
        {
            $productType = RPS::File::Sale::TYPE_TRACK;
        }
        elsif( $productType eq 'A' )
        {
            $productType = RPS::File::Sale::TYPE_ALBUM;
        }
        else 
        {
            return $self->handleError("Unknown product type: $productType", RPS::DB::Item::SaleImportError::kErrorProductType);
        }
    } else {
        my $deliveryType   = lc $self->_getByFieldName( 'deliveryType' );        
        if (!$deliveryType)  
        {
            return $self->handleError("Delivery type missing", RPS::DB::Item::SaleImportError::kErrorNonqualifying);
        }        
        
        my $deliveryFormat = lc $self->_getByFieldName( 'deliveryFormat' ); 
        if (!$deliveryFormat)  
        {
            return $self->handleError("Delivery format missing", RPS::DB::Item::SaleImportError::kErrorNonqualifying);
        }    
        
        $productType = $deliveryFormatMap{ $deliveryFormat }{ $deliveryType }{ product_type }; 
        if ($productType) {
            # Adding an exception for the unknown.
            if( $deliveryType =~ /unknown/i && $deliveryFormat =~ /download/i && !$self->isrc() ) {
                return RPS::File::Sale::TYPE_ALBUM;
            } else {            
		        return $productType;
		    }        
		} else {
            return $self->handleError("Unknown deliveryType($deliveryType) deliveryFormat($deliveryFormat)", RPS::DB::Item::SaleImportError::kErrorProductType);
		}        
    }
}        

sub free 
{
    my $self = shift;
    my $price = $self->price;
    return ( $price == 0 ) ? 1 : 0;
}

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

    if( $price =~ /e-/ )
    {
        # Note: the high precision is so that we can capture revenue like .00000000003
        # Effectively we'll store this as a zero since the DB only has 8 digits, but
        # for calculation purposes it'll let us assign a unit to a "zero" revenue line.
        # 
        $price = sprintf("%.18f", $price); # convert scientific notation to decimal
    }

    if( $price =~ /^\((\d*\.?\d*)\)$/ )
    {
        $price = $1 * -1;
    }     
    
    return $price;     
}

sub units {
    my $self = shift;
    my $units = $self->_getByFieldName( 'units' ) || return;
    $units =~ s/,//g;
    $units =~ s/\s+//g;   
    if( $units =~ /^\((\d*\.?\d*)\)$/ )
    {
        $units = $1 * -1;
    }
     
    my $price = $self->price;

    # For this importer, We'll follow the sign of the revenue to determine
    # the sign of the units (FB1168).
    #
    if( $price && $units )
    {
        if( $price < 0 )
        {
            $units = 0 - $units if( $units > 0 ); # price is negative, force negative units
        }
        else
        {
            $units = abs($units) if( $units < 0 ); # price is positive, force positive units
        }
    }

    return $units;
}

sub unitPrice {
    my $self = shift;
    return 0 if( $self->price == 0 );
    return $self->SUPER::unitPrice();
}

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

    if ( $isrc )
    {
        $isrc = Common::Util::normalize_isrc($isrc);
        if ($isrc =~ /^\w/) 
        {            
            return $isrc;
        }
    }  
}

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

    if ( $upc )
    {
        $upc = Common::Util::normalize_upc($upc);
        if ($upc =~ /^\d/) 
        {            
            return $upc;
        }
    }  

    # This also catches UPC eq '0', which we don't 
    # want either (FBoD15108). Besides, it's always
    # good to return something explicitly.
    return undef;
}

sub albumName {
    my $self = shift;
    my $isrc = $self->isrc();
    my $name = $self->_getByFieldName( 'albumName' );
    my $sheetName = lc $self->{sheetname};
    # On the domestic sheet, album name is always included.
    #    
    if ( !$isrc || $sheetName eq 'domestic' )
    {    
        return $name;
    } 
}

sub trackName {
    my $self = shift;
    my $isrc = $self->isrc();
    my $name = $self->_getByFieldName( 'trackName' );
    if ( $isrc )
    {    
        return $name;
    } 
}
                
sub serviceID {
    my $self = shift;
    my $serviceName = $self->_getByFieldName( 'serviceID' ) || return;

    my $serviceID = $self->getServiceID(lc ($serviceName)); # See ADACommon
    
    if (!$serviceID && $serviceName =~ /[[:^ascii:]]/)
    {                  
        # Case 15436 - defaulting service names with incompatible characters to ADA
        $serviceID = Client::Service::DSP_ADA;        
    }
    
    if (!$serviceID)
    {   
        return $self->handleError("Unknown service: $serviceName", RPS::DB::Item::SaleImportError::kErrorService);
    } 
    else
    {
        return $serviceID;   
    }
}

sub _normalizeSheetName {
    my $self = shift;
    my $sname = shift;
    my $name;

    $name = $sname;
    if ( $sname =~ /domestic digital/i )
    {
        $name = "domestic";
    }
    elsif ( $sname =~ /int\'l digital/i )
    {
        $name = "international";
    }    

    return $name;
}

sub _normalizeDate {
    my($dt) = @_;
    my $date = $dt;
    if ( $dt =~ m/^\d{5}$/ ) {
        $date = Spreadsheet::ParseExcel::Utility::ExcelFmt( "yyyy-mm-dd", $dt );
    }
    return $date;
}

sub _getDatesFromFileName
{
    my $self = shift;
    my $date = shift;

    my ($dateBegin, $dateEnd, $month, $year);

    if( $date =~ m/(january|february|march|april|may|june|july|august|september|october|november|december)[_ ](\d{4})/i )
    {
        $month = Decode_Month($1);
        $year  = $2;

#print STDERR "DEBUG: _getDatesFromFileName: fmonth($1) month($month) year($year)\n";
        $dateBegin = sprintf("%04d-%02d-%02d", $year, $month, 1);
        $dateEnd   = sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month));
    }
    elsif ($date =~ m/([a-z]+)\s*(\d{4})\./i) {

        $month = Decode_Month($1);
        $year  = $2;

        $dateBegin = sprintf("%04d-%02d-%02d", $year, $month, 1);
        $dateEnd   = sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month));
    }
    elsif ($date =~ m/(\d{4})-(\d{1,2})/) {
        $year  = $1;
        $month = $2;
        
        $dateBegin = sprintf("%04d-%02d-%02d", $year, $month, 1);
        $dateEnd   = sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month));
    }
    elsif ($date =~ m/(\d{2})-(\w{3})/) {

        $month = Decode_Month($2);
        $year  = "20" . $1;

        $dateBegin = sprintf("%04d-%02d-%02d", $year, $month, 1);
        $dateEnd   = sprintf("%04d-%02d-%02d", $year, $month, Days_in_Month($year, $month));
    }    
    else {
        return undef;
    }

    return ($dateBegin, $dateEnd);
}

sub _isValidSaleRecord 
{
    my $self = shift;
    my $units  = $self->units;
    my $price  = $self->price;

    return undef if ( !$units && $price && $price < 0 );
    
    # We're going to skip the tabs we don't care about.
    my $sheetName = $self->_normalizeSheetName( lc $self->{sheetname} );
    return undef if ( $sheetName ne 'domestic' && $sheetName ne 'international' );
    return $self->SUPER::_isValidSaleRecord();
}


## MapFace Stuff

sub _mapFaceServiceID {
	return ('serviceID', 'countryCode');
}

sub _mapFaceCountryCode {
	return ('countryCode');
}

sub _mapFaceProductType {
	return ('productType', 'deliveryType', 'deliveryFormat');
}

sub _mapFaceFormatType {
	return ('mediaCode', 'deliveryType', 'deliveryFormat');
}

sub _mapFaceMediaType {
	return ('mediaCode', 'deliveryType', 'deliveryFormat');
}


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