package FileTracker::Summary;

use strict;
use warnings;
use Carp;
use URI::Escape;

use lib '/app/tools/sale_import/lib';
use File::Util;

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

use lib '/app/tools/data_classes/lib';
use Client::Service;
use Period::RoyaltyPeriod;

use lib ('/app/tools/common/lib');
use Common::Consts;
use Common::Util;
use RSApache::Session;

# in leiu of a "new" subroutine.
use RSApache::RSApp;
use base 'RSApache::RSApp';

my $Session;
my $CurrentUser;
my $Period;

sub execute {
    my $self = shift;
    my $current_period;
    $self->Stylesheet("tracker.xsl");

    # ---------------------------------------
    # check login
    # ---------------------------------------
    $Session = new RSApache::Session();
    if ( !$Session->IsValid() ) {

        # redirect them
        $self->Redirect( $Common::Consts::URLS{login} . "?redirect=" . $self->GetRequestString() );
        return 1;
    }

    # ---------------------------------------
    # check general access
    # ---------------------------------------
    $CurrentUser = $Session->ActiveUser;
    $self->SetNavigationAccess($CurrentUser);
    if ( $CurrentUser->CanAccess( $self->App ) ) {
        my $edit_area = "tracker_edit";
        $self->AddAccessXML( type => $edit_area, value => $CurrentUser->CanAccess($edit_area) );
        $self->{xml}->{CurrentUser} = $CurrentUser->GetObjectXML();
    } else {
        $self->{xml}->{CurrentUser}  = $CurrentUser->GetObjectXML();
        $self->{xml}->{AccessDenied} = 1;
        return 1;
    }

    my $cmd = $self->GetParam("cmd");

    return 1 if ( $cmd eq 'edit_period' && $self->PeriodName );
    return 1 if ( $cmd eq 'notes'       && $self->Notes );

    # ---------------------------------------
    # load period
    # ---------------------------------------
    $Period = new Period::RoyaltyPeriod();
    my $period_param = $self->GetParam("period");
    if ( !defined $period_param ) {

        # just get the current period
        $Period->LoadCurrent();
        $current_period = 1;
    } else {

        # lookup by id
        $Period->Load( period_id => $period_param );
    }

    # ---------------------------------------
    # Stuff we can only do to the current period
    # ---------------------------------------
    if ( $current_period && $cmd ) {
        #
        # These return immediately
        #
        if ( 'finish' eq $cmd && $self->FinishImport() ) {
            return 1;
        } elsif ( 'revenue' eq $cmd && $self->SetRevenue() ) {
            return 1;
        } elsif ( 'currency' eq $cmd && $self->SetConversionRate() ) {
            return 1;
        }

        # trigger a "NEW" file to be imported
        elsif ( 'import' eq $cmd && $self->DoFileImport() ) {
            return 1;
        }

        # download an uploaded file
        elsif ( 'saveas' eq $cmd && $self->DoFileSave() ) {
            return 1;
        }
        #
        # These fall through to the rest of the handler
        #
        elsif ( 'exceptions' eq $cmd ) {
            $self->DoExceptionsReport();
        } elsif ( 'delete' eq $cmd ) {
            $self->DoFileDelete();
        } elsif ( 'checkrevenue' eq $cmd ) {
            $self->DoRevenueChecked();
        } elsif ( 'upload' eq $cmd ) {
            $self->DoFileUpload();
        } elsif ( 'close' eq $cmd ) {
            $self->DoClosePeriod();
        } elsif ( 'reopen' eq $cmd ) {
            $self->DoReopenFile();
        } elsif ( 'allexceptions' eq $cmd ) {
            $self->DoAllExceptionsReport();
        } elsif ( 'exceptionsdl' eq $cmd ) {
            $self->DownloadAllExceptionsFile();
        } elsif ( 'currentrecon' eq $cmd ) {
            $self->DoCurrentReconReport();
        } elsif ( 'trackerdl' eq $cmd ) {
            $self->DownloadTrackerToExcel();
        } elsif ( 'forcesplit' eq $cmd ) {
            $self->DoForceSplit();
        } elsif ( 'qwikclose' eq $cmd ) {
            $self->DoQwikClose();
        }
    }

    # ---------------------------------------
    # Stuff we can only do to closed periods
    # ---------------------------------------
    elsif ($cmd) {

        # download a royalty report
        if ( 'download' eq $cmd && $self->DownloadRoyaltyReport() ) {
            return 1;
        }
    }

    # --------------------------------------
    # File Summary Listing (main page)
    # --------------------------------------
    $self->DoFileListing();

    # set period xml
    $self->{xml}->{Period} = $Period->GetObjectXML();

    # --------------------------------------
    ## Set File Status For Current Period Reports
    # --------------------------------------
    $self->SetExceptionsFileStatus();

    return 1;
}

# ------------------------------------------------
# Sub Commands Within This App
# ------------------------------------------------
sub Notes {
    my $self = shift;
    return undef
      unless ( $CurrentUser->AccessLevel == User::User::ACCESS_RSREP
        || $CurrentUser->AccessLevel == User::User::ACCESS_RSADMIN );

    my $file_id = $self->GetParam("file");
    my $file = RPS::File::File->new( file_id => $file_id );
    return undef unless ($file);

    if ( $self->GetParam("sub_cmd") eq "update" ) {
        $file->Notes( $self->GetParam("notes") );
        $file->Save();
        $self->AddMessageXML( type => "success", code => "notes_edited" );
        return 0;
    }

    # else view notes
    $self->{xml}->{File} = $file->GetObjectXML();

    return 1;
}

sub PeriodName {
    my $self = shift;
    return undef
      unless ( $CurrentUser->AccessLevel == User::User::ACCESS_RSREP
        || $CurrentUser->AccessLevel == User::User::ACCESS_RSADMIN );

    my $periodID = $self->GetParam("period");
    my $period = new Period::RoyaltyPeriod( period_id => $periodID );
    return undef unless ($period);

    if ( $self->GetParam("sub_cmd") eq "update" ) {
        $period->Name( $self->GetParam("period_name") );
        $period->Save();
        $self->AddMessageXML( type => "success", code => "period_edited" );
        return 0;
    }

    # else view current period name
    $self->{xml}->{Period} = $period->GetObjectXML();

    return 1;
}

sub DoFileListing {
    my $self = shift;

    # get all files for this period
    my $files = RPS::File::Files->new();
    $files->GetByPeriod( period_id => $Period->PeriodID );
    my $total        = 0;
    my $closed_count = 0;
    while ( my $fileObj = $files->GetNext() ) {
        $total++;
        $closed_count++ if ( $fileObj->FileStatus == File::File::STATUS_CLOSED() );

        if ( $fileObj->FileStatus == File::File::STATUS_PROCESSING() ) {
            my $sale = RPS::File::Sale->new();
            $fileObj->Records( $sale->GetRecordCount( $fileObj->FileID ) );
        }

        # get $fileObj xml
        push @{ $self->{xml}->{Files}->{File} }, $fileObj->GetObjectXML();
    }
    $self->{xml}->{Files}->{UnprocessedCount} = $total - $closed_count;

    # we need this for later
    $self->{ClosedCount} = $closed_count;
}

sub DoExceptionsReport {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file_id = $self->GetParam("file");
    my $file = RPS::File::File->new( file_id => $file_id );

    if ( $file && $file->FileID == $file_id && $file->RemainingExceptions > 0 ) {
        my $file_path = $file->GetExceptionsFile();

        if ( -e $file_path ) {
            open my $fh, "< $file_path";
            my $tmp_name;
            ( $tmp_name = $file_path ) =~ s/.*\/(.*)$/$1/;
            $self->FileDownloadName($tmp_name);
            $self->FileDownload($fh);
        } else {
            $self->AddMessageXML( type => "error", code => "download_unavailable" );
        }
    }
}

sub DoAllExceptionsReport {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $filename = $self->GetAllExceptionsFilename;

    ## delete file if it exists
    unlink $filename if ( -e $filename );
    ## delete temp file if it exists
    unlink $filename . "-tmp" if ( -e $filename . "-tmp" );

    ## start script running
    my $script = "/app/tools/sale_import/bin/dump_all_exceptions.pl";
    my $args   = $self->ClientID . " " . $filename;
    system("$script $args &");
    sleep 1;

    $self->Redirect( "/app/" . $self->App );
}

sub DoCurrentReconReport {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my ( $file, $clientNameClean ) = RPS::Sale::Report->GetRoyaltyReportFile(
        period_id => 0,
        client_id => $self->ClientID,
        file_type => 'reconciliation',
    );

    ## delete if exists
    unlink $file if ( -e $file );

    unless ( RPS::Sale::Report->CreateReconciliationReport( client_id => $self->ClientID, period_id => 0 ) ) {
        $self->AddMessageXML( type => "error", code => "download_unavailable" );
    }

    if ( -f $file ) {
        open( my $fh, $file );
        $self->FileDownloadName( $clientNameClean . "_Recon_Period0.xls" );
        $self->FileDownload($fh);
        return 1;
    }
}

sub DownloadTrackerToExcel {
    my $self = shift;

    my ( $file, $clientNameClean ) = RPS::Sale::Report->GetTrackerExcelFile( $self->ClientID );

    ## delete if exists
    unlink $file if ( -e $file );

    if ( $CurrentUser->CanAccess("tracker_edit") ) {
        ## add flag to include notes field
        RPS::Sale::Report->CreateTrackerExcelFile( $self->ClientID, 1 );
    } else {
        RPS::Sale::Report->CreateTrackerExcelFile( $self->ClientID );
    }

    if ( -f $file ) {
        open( my $fh, $file );
        $self->FileDownloadName( $clientNameClean . "_Summary.xls" );
        $self->FileDownload($fh);
        return 1;
    } else {
        $self->AddMessageXML( type => "error", code => "download_unavailable" );
    }
}

sub SetExceptionsFileStatus {
    my $self = shift;

    my $filename = $self->GetAllExceptionsFilename;
    $self->{xml}->{ExceptionsFile}->{Filename} = $filename;

    if ( -f $filename ) {
        ## file exists
        $self->{xml}->{ExceptionsFile}->{Status} = 2;
    } elsif ( -f $filename . "-tmp" ) {
        ## file is being processed
        $self->{xml}->{ExceptionsFile}->{Status} = 1;
    } else {
        ## file does not exist
        $self->{xml}->{ExceptionsFile}->{Status} = 0;
    }
}

sub DownloadAllExceptionsFile {
    my $self = shift;

    my $filename = $self->GetAllExceptionsFilename;

    return undef unless ( -f $filename );

    open( my $fh, $filename );
    my $clean_name = Common::Util::clean_name( $self->{xml}->{CurrentUser}->{ClientName} );
    $self->FileDownloadName( $clean_name . "_all_exceptions.txt" );
    $self->FileDownload($fh);
    return 1;
}

sub DownloadCurrentReconReport {
    my $self = shift;
    my ( $file, $clientNameClean ) = RPS::Sale::Report->GetRoyaltyReportFile(
        period_id => 0,
        client_id => $self->ClientID,
        file_type => 'reconciliation',
    );
}

sub GetAllExceptionsFilename {
    my $self = shift;

    my $clean_name = Common::Util::clean_name( $self->{xml}->{CurrentUser}->{ClientName} );

    my $dir = "/app/shared/sale_import/" . $clean_name;
    `mkdir $dir` unless ( -e $dir );

    $dir .= "/exceptions";
    `mkdir $dir` unless ( -e $dir );

    my $filename = $dir . "/all_exceptions.txt";

    return $filename;
}

sub DoFileImport {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file_id = $self->GetParam("file");
    my $file = RPS::File::File->new( file_id => $file_id );

    if ( $file && $file->FileStatus == File::File::STATUS_NEW() ) {
        my $script = "/app/tools/sale_import/bin/import_sales_file.pl " . $self->ClientID . " " . $file_id;
        system("$script &");

        # allow time for the file status to change.
        sleep 1;

        $self->Redirect( "/app/" . $self->App );
        return 1;
    }
}

sub DoFileDelete {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file_id = $self->GetParam("file");
    my $file = RPS::File::File->new( file_id => $file_id );

    return undef if ( $file->ParentFileID || $file->HasChild > 0 );

    if ( $file && $file->FileStatus != File::File::STATUS_CLOSED() ) {
        if ( $file->Delete() ) {
            $self->AddMessageXML( type => "success", code => "file_deleted" );
            $self->{xml}->{DeletedFile} = $file->OrigFileName;
        } else {
            $self->AddMessageXML( type => "error", code => "file_not_deleted" );
        }
    }
}

sub DoRevenueChecked {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file_id = $self->GetParam("file");
    my $file = RPS::File::File->new( file_id => $file_id );

    if ( $file && $file->FileStatus != File::File::STATUS_CLOSED() && !( $file->ParentFileID ) ) {
        my $action = $self->GetParam("sub_cmd");
        ##my $status = $file->RevenueChecked(); ## current status
        ##$status = ($status + 1) % 2;          ## toggle status
        my $status = ( $action eq "set" ) ? 1 : 0;

        if ( defined $file->RevenueChecked($status) ) {
            $file->Save();
            $self->AddMessageXML( type => "success", code => "revenue_check_set" );
        } else {
            $self->AddMessageXML( type => "error", code => "revenue_check_not_set" );
        }
    }
}

sub DoFileUpload {
    my $self = shift;

    # anyone can upload files now
    # (see comments below about importer)
    # return undef if(! $CurrentUser->CanAccess("tracker_edit"));

    my $file_param = $self->GetParam("fileUpload");
    if ( defined $file_param && $file_param ne '' ) {
        my $new_file_id = $self->uploadFile($file_param);
        if ($new_file_id) {

            # to avoid duplicate file uploads when someone refreshes the page
            # we are going to just redirect instead of posting success xml back.
            $self->Redirect( "/app/" . $self->App );

            # launch file importer only if RoyaltyShare user
            if (   $CurrentUser->AccessLevel == User::User::ACCESS_RSREP
                || $CurrentUser->AccessLevel == User::User::ACCESS_RSADMIN ) {
                my $script = "/app/tools/sale_import/bin/import_sales_file.pl " . $self->ClientID . " " . $new_file_id;
                system("$script &");

                # this gives the import_sales_file script enough time to
                # start the import process, thus putting the file into
                # "PROCESSING" status, which is what we want.
                sleep 1;
            }
        } else {
            $self->AddFormFieldValue( name => "fileUpload", error_type => $self->ErrorCode );
        }
    }
}

sub DoFileSave {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file_id = $self->GetParam("file");
    my $file = RPS::File::File->new( file_id => $file_id );

    if ( $file && $file->FileID == $file_id ) {
        my $fileOnDisk = $file->FileDir . "/" . $file->FileName;

        if ( -f $fileOnDisk ) {
            open my $fh, "<$fileOnDisk";
            $self->FileDownloadName( $file->OrigFileName );
            $self->FileDownload($fh);
            return 1;
        } else {
            $self->AddMessageXML( type => "error", code => "download_unavailable" );
        }
    }
    return undef;
}

sub uploadFile {
    my $self      = shift;
    my $file_path = shift;

    my $orig_file_name = $file_path;
    $orig_file_name =~ s/.*[\/\\](.*)/$1/;
    my $fh = $self->{cgi}->upload("fileUpload");

    if ( eof $fh ) {
        $self->AddMessageXML( type => "error", code => "file_is_empty" );
        return undef;
    }

    # this lets us reset the file handle
    my $start_of_file = tell($fh);

    # -------------------------

    # get md5sum and check for duplicate file
    my $md5_sum = Common::Util::md5sum($fh);
    if ( !defined $md5_sum ) {
        $self->ErrorCode("file_upload_unreadable");
        return undef;
    }

    # reset the file handle to the start of the file
    seek( $fh, $start_of_file, 0 );

    my $files = RPS::File::Files->new();
    if ( $files->GetByOrigName( file_name => $orig_file_name ) || $files->GetByMD5( md5_sum => $md5_sum ) ) {
        $self->ErrorCode("file_upload_duplicate");
        return undef;
    }

    # -------------------------

    $md5_sum = 'null'
      unless ( $CurrentUser->AccessLevel == User::User::ACCESS_RSREP || $CurrentUser->AccessLevel == User::User::ACCESS_RSADMIN );

    my $sf          = new RPS::Sale::File();
    my $new_file_id = $sf->SimpleUploadFromWeb(
        fh        => $fh,
        filename  => $orig_file_name,
        period_id => $Period->PeriodID,
        md5_sum   => $md5_sum,
    );
    if ($new_file_id) {
        return $new_file_id;
    } else {
        $self->ErrorCode("file_upload_saveerror");
        return undef;
    }
}

sub DoClosePeriod {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    # you can only close the currnent period (period 0)
    if ( $Period->PeriodID == 0 ) {

        # are the conditions right?
        # verify we are in the current period AND we have at least one closed file.

        # get num closed files
        my $closed_count = RPS::File::Files->GetNumClosed();
        if ( $closed_count && $closed_count > 0 ) {

            # Closing a period means:
            # 	1. Setting EndDate for this period object
            # 	2. creating a new period object with start date of today
            #	3. associate finished files with new period
            my $new_period_id = $self->closePeriod();
            if ( $new_period_id && $new_period_id > 0 ) {

                # dump_royalty_report takes two args: client_id and period_id
                my $run_report_script = "/app/tools/sale_import/bin/dump_royalty_report.pl -c " . $self->ClientID . " -p " . $new_period_id;
                system("$run_report_script &");

                $self->Redirect( "/app/tracker?period=" . $new_period_id );
            } else {
                $self->AddMessageXML( type => "error", code => $self->ErrorCode );
            }

            return 1;
        } else {

            # the template shouldn't let someone close a period
            # without the above conditions satisfied. Not sure
            # if we want to send an error message back or not.
        }
    }
}

sub DoReopenFile {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file_id = $self->GetParam("file");
    my $file = RPS::File::File->new( file_id => $file_id );

    if ( $file && $file->FileStatus == File::File::STATUS_CLOSED() ) {
        if ( $file->ReopenFile() ) {
            $self->AddMessageXML( type => "success", code => "file_reopened" );
        } else {
            $self->AddMessageXML( type => "error", code => "file_not_reopened" );
        }
    }
}

sub closePeriod {
    my $self  = shift;
    my $today = Common::Util::today();

    # create new period
    my $new_period = new Period::RoyaltyPeriod();
    $new_period->StartDate( $Period->StartDate );
    $new_period->EndDate($today);
    $new_period->Name( $Period->Name );
    $new_period->Save();

    if ( !$new_period->PeriodID ) {
        $self->ErrorCode("close_period_failed");
        return undef;
    }

    # update finished files to be associated with new period
    my $files = RPS::File::Files->new();
    if ( !$files->StartPeriod( $new_period->PeriodID ) ) {
        $self->ErrorCode("close_period_failed");
        return undef;
    }

    # reassign start date of current period
    $Period->StartDate($today);
    $Period->Name("");
    $Period->Save();

    return $new_period->PeriodID;
}

sub DoForceSplit {
    my $self = shift;

    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file_id = $self->GetParam("file");

    my $file = RPS::File::File->new( file_id => $file_id );
    return undef if ( !$file );

    # must still be open
    # shouldn't be able to get to here from the UI, so return undef
    return undef if ( $file->FileStatus == File::File::STATUS_CLOSED );

    my $submit = $self->GetParam("submit");
    if ($submit) {

        # split the file
        my $new_file = $file->Split();
        if ($new_file) {
            $self->{xml}->{NewFile} = $new_file->GetObjectXML();
        } else {
            $self->AddMessageXML( type => "error", code => "split_failed" );
            $self->{xml}->{File} = $file->GetObjectXML();
            return 1;
        }

        my $success = $file->FinishImport();

        if ( !$success ) {
            $self->AddMessageXML( type => "error", code => "finish_failed" );
        }
    }

    $self->{xml}->{File} = $file->GetObjectXML();
}

sub FinishImport {
    my $self = shift;
    my $file_id = shift || $self->GetParam("file");

    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file = RPS::File::File->new( file_id => $file_id );
    return undef if ( !$file );

    # must still be open
    # shouldn't be able to get to here from the UI, so return undef
    return undef if ( $file->FileStatus == File::File::STATUS_CLOSED );

    # must have revenue first
    if ( !$file->Revenue ) {
        my $redirect = "/app/tracker?file=$file_id&cmd=revenue&redirect=" . $self->GetRequestString();
        $self->Redirect($redirect);
        return 1;
    }

    # must have conversion rate, too
    if ( $file->CurrencyCode ne 'USD' && !$file->InputConversionRate ) {
        my $redirect = "/app/tracker?file=$file_id&cmd=currency&redirect=" . $self->GetRequestString();
        $self->Redirect($redirect);
        return 1;
    }

    # must have had revenue checked, or be a child
    if ( $file->ParentFileID == undef && $file->RevenueChecked == 0 ) {
        $self->AddMessageXML( type => "error", code => "finish_failed" );
        return 1;
    }

    my $submit = $self->GetParam("submit");
    if ($submit) {
        if ( $file->RemainingExceptions > 0 ) {

            # split the file
            my $new_file = $file->Split();
            if ($new_file) {
                $self->{xml}->{NewFile} = $new_file->GetObjectXML();
            } else {
                $self->AddMessageXML( type => "error", code => "split_failed" );
                $self->{xml}->{File} = $file->GetObjectXML();
                return 1;
            }
        }

        my $success = $file->FinishImport();

        if ( !$success ) {
            $self->AddMessageXML( type => "error", code => "finish_failed" );
        }
    }

    $self->{xml}->{File} = $file->GetObjectXML();
}

sub DoQwikClose {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $submit = $self->GetParam("submit");
    my @files  = $self->GetParam("file");

    foreach my $file_id (@files) {
        ## not checking for errors... if a file fails, it'll stay open
        $self->FinishImport($file_id);
    }
    $self->{xml}->{ActionCompleted} = "QwikClose";
}

sub SetConversionRate {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file_id = $self->GetParam("file");

    my $file = RPS::File::File->new( file_id => $file_id );
    return undef if ( !$file || $file->FileStatus == File::File::STATUS_CLOSED );

    my $currency_param = $self->GetParam("currency");

    # are we setting it? yes, we accept zero.
    if ( defined $currency_param ) {
        $currency_param =~ s/,//g;
        my $success = $file->SetConversionRate($currency_param);
        if ($success) {
            my $redirect = uri_escape( $self->GetParam("redirect") );
            if ( !$redirect ) {
                $redirect = "/app/" . $self->App;
            }
            $self->Redirect($redirect);
        } else {
            $self->AddMessageXML( type => "error", code => "invalid_currency" );
            $self->{xml}->{File} = $file->GetObjectXML();
        }
    }

    # just display info
    else {
        $self->{xml}->{File} = $file->GetObjectXML();
    }

    return 1;
}

sub SetRevenue {
    my $self = shift;
    return undef if ( !$CurrentUser->CanAccess("tracker_edit") );

    my $file_id = $self->GetParam("file");
    my $file = RPS::File::File->new( file_id => $file_id );
    return undef if ( !$file || $file->FileStatus == File::File::STATUS_CLOSED );

    my $revenue_param = $self->GetParam("revenue");

    # are we setting it?
    if ($revenue_param) {
        $revenue_param =~ s/,//g;
        my $success = $file->SetRevenue($revenue_param);
        if ($success) {
            my $redirect = uri_escape( $self->GetParam("redirect") );
            if ( !$redirect ) {
                $redirect = "/app/" . $self->App;
            }
            $self->Redirect($redirect);
        } else {
            $self->AddMessageXML( type => "error", code => "invalid_revenue" );
        }
    }

    # just display info
    else {
        $self->{xml}->{File} = $file->GetObjectXML();
    }

    return 1;
}

sub DownloadRoyaltyReport {
    my $self            = shift;
    my $file_type_param = $self->GetParam("file_type");

    my ( $file, $clientNameClean ) = RPS::Sale::Report->GetRoyaltyReportFile(
        period_id => $Period->PeriodID,
        client_id => $self->ClientID,
        file_type => $file_type_param,
    );

    if ( -f $file ) {
        my $periodName = $Period->Name;
        $periodName =~ s/\s+/_/g;
        $periodName =~ s/\W//g;

        my $fileName = uc($clientNameClean);
        $fileName .=
            $file_type_param =~ m/account/i ? '_DGRoy_'
          : $file_type_param =~ m/recon/i   ? '_AcctRec_'
          :                                   '_RoyaltyReport_';

        $fileName .= $periodName || sprintf( "%s_to_%s", $Period->StartDate, $Period->EndDate );

        if ( $file =~ /(\.\w+)$/ ) {
            $fileName .= $1;
        }

        open( my $fh, $file );
        $self->FileDownloadName($fileName);
        $self->FileDownload($fh);
        return 1;
    } else {

        # do we want to respawn this process? It's possible the
        # original dump_royalty_report.pl is still running, right?

        # dump_royalty_report takes two args: client_id and period_id
        # my $run_report_script = "/app/tools/sale_import/bin/dump_royalty_report.pl -c ".$self->ClientID ." -p".$new_period_id;
        # system("$run_report_script &");

        $self->AddMessageXML( type => "error", code => "download_unavailable" );
        return undef;
    }
}

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