#------------------------------------------------------------
# Copyright (C) 2009 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------

package RPS::Mechanical::US::Process::CreateStatement;

use strict;

use lib '/app/tools/common/lib';
use lib '/app/tools/rps/lib';
use lib '/app/tools/raptor/lib';

use POSIX qw(ceil);

use Common::Assert;
use Common::DB::Item::Client;
use Common::Log;
use Common::RSMath;
use Common::Util;
use Data::Dumper;
use Raptor::DB::Item::File;
use Raptor::DB::Item::Sale;
use RPS::DB::Item::Album;
use RPS::DB::Item::AlbumContract;
use RPS::DB::Item::Artist;
use RPS::DB::Item::BonusTrack;
use RPS::DB::Item::ControlledComposition;
use RPS::DB::Item::FinanceAccount;
use RPS::DB::Item::LicenseReserve;
use RPS::DB::Item::LicenseReserveRun;
use RPS::DB::Item::Master;
use RPS::DB::Item::MechanicalCarryover;
use RPS::DB::Item::MechanicalRun;
use RPS::DB::Item::MechanicalRunCarryover;
use RPS::DB::Item::MechanicalStatement;
use RPS::DB::Item::MechanicalStatementAdjustmentItem;
use RPS::DB::Item::MechanicalStatementCrossedLicenseTransaction;
use RPS::DB::Item::MechanicalStatementItem;
use RPS::DB::Item::MechanicalStatementLicense;
use RPS::DB::Item::MechanicalStatementLicenseTransaction;
use RPS::DB::Item::MechanicalStatementPublisher;
use RPS::DB::Item::MechanicalStatementPublisherTransaction;
use RPS::DB::Item::MechanicalStatementTrack;
use RPS::DB::Item::MechanicalStatementTransaction;
use RPS::DB::Item::PendingTransaction;
use RPS::DB::Item::Product;
use RPS::DB::Item::ProductTrack;
use RPS::DB::Item::Publisher;
use RPS::DB::Item::PublisherAccount;
use RPS::DB::Item::PublisherIndirectBalanceAccount;
use RPS::DB::Item::PublisherTrackCrossedLicenseAccount;
use RPS::DB::Item::RegionCountryMap;
use RPS::DB::Item::ReserveLiquidation;
use RPS::DB::Item::SaleLicenseMap;
use RPS::DB::Item::SalePublisherLicenseMap;
use RPS::DB::Item::SalePublisherMap;
use RPS::DB::Item::SaleRunMap;
use RPS::DB::Item::Song;
use RPS::DB::Item::StatRate;
use RPS::DB::Item::Track;
use RPS::DB::Item::TrackLicense;
use RPS::Mechanical::US::MechanicalRun;
use RPS::Mechanical::Process::CreateStatement;
use RPS::Mechanical::Process::SaleException;

use RPS::Mechanical::Process::CreateStatement::Complex;
use base 'RPS::Mechanical::Process::CreateStatement::Complex';

sub _defaultIssueStatRateID {

    my ( $self, $licenseType ) = @_;

    if ( $licenseType == RPS::DB::Item::TrackLicense::kRingtone ) {
        return 28;
    } else {
        return 16;
    }
}

sub _getAllPossibleLicenses {
    my ($self) = @_;

    return RPS::DB::Item::TrackLicense->GetLicensesForPublisherStatement( $self->_publisherID(), $self->_payorID() );
}

sub _currencyCode {
    my ($self) = @_;
    return 'USD';
}

sub _getStatRates {
    my ($self) = @_;
    return RPS::DB::Item::StatRate->GetRatesUS();
}

sub _createLicenseReserve {
    my ( $self, $statementItem, $units, $periodsRemaining ) = @_;

    my $newReserve = RPS::DB::Item::LicenseReserve->Create(
        track_license_id           => $statementItem->track_license_id,
        original_statement_item_id => $statementItem->mechanical_statement_item_id,
        product_id                 => $statementItem->product_id,
        sale_stat_rate_id          => $statementItem->sale_stat_rate_id,
        issue_stat_rate_id         => $statementItem->issue_stat_rate_id,
        units                      => $units,
        effective_rate             => $statementItem->net_rate,
        periods_remaining          => $periodsRemaining,
    );
    return $newReserve;
}

sub _getLicensesWithPendingTransactions {
    my ($self) = @_;
    return RPS::DB::Item::TrackLicense->GetLicensesWithPendingTransactionsForMechanicalStatement(
        $self->_publisherID(),
        $self->_payorID()
    );
}

sub _getCrossedLicensesWithPendingTransactions {
    my ($self) = @_;
    return RPS::DB::Item::TrackLicense->GetCrossedLicensesWithPendingTransactionsForMechanicalStatement(
        $self->_publisherID(),
        $self->_payorID()
    );
}

sub _reserveType {
    my ($self) = @_;
    return RPS::DB::Item::ReserveLiquidation::kTypePublishingLicense;
}

sub _ringtoneStatRateType {
    my ($self) = @_;
    return RPS::DB::Item::StatRate::kUSRingStatRateType;
}

sub _lookupTrackLicense {
    my ( $self, $id ) = @_;
    return RPS::DB::Item::TrackLicense->Lookup( track_license_id => $id );
}

sub _createStatementItem {
    my ( $self, $statementID, $trackLicenseID, $trackLicensePublisherID, $productID, $upc, $isrc, $saleStatRateID, $issueStatRateID ) = @_;
    my $item = RPS::DB::Item::MechanicalStatementItem->Create(
        mechanical_statement_id => $self->{_statementID},
        track_license_id        => $trackLicenseID,
        publisher_id            => $trackLicensePublisherID,
        product_id              => $productID,
        upc                     => $upc,
        isrc                    => $isrc,
        sale_stat_rate_id       => $saleStatRateID,
        issue_stat_rate_id      => $issueStatRateID,
    );
    return $item;
}

sub _createStatementLicense {
    my ( $self, $trackLicense ) = @_;

    my $item = RPS::DB::Item::MechanicalStatementLicense->Create(
        mechanical_statement_id => $self->_statementID(),
        track_license_id        => $trackLicense->track_license_id(),
        region_id               => $trackLicense->region_id(),
    );
    return $item;
}

sub _getStatementLicenseItemsByStatementID {
    my ( $self, $statementID ) = @_;
    return RPS::DB::Item::MechanicalStatementLicense->GetByMechanicalStatementID($statementID);
}

sub _getStatementTrackItemsByStatementID {
    my ( $self, $statementID ) = @_;
    return RPS::DB::Item::MechanicalStatementTrack->GetByMechanicalStatementID($statementID);
}

sub _getFileLabel {
    my ( $self, $run ) = @_;
    return RPS::Mechanical::US::MechanicalRun::GenerateFileLabel( $run->label );
}

sub _lookupPublisher {
    my ( $self, $publisherID ) = @_;
    return RPS::DB::Item::Publisher->Lookup( publisher_id => $publisherID );
}

sub _lookupPublisherAccount {
    my ( $self, $publisherID, $payorID ) = @_;
    return RPS::DB::Item::PublisherAccount->Lookup( publisher_id => $publisherID, payor_id => $payorID );
}

sub _createPublisherAccount {
    my ( $self, $publisherID, $payorID ) = @_;
    return RPS::DB::Item::PublisherAccount->Create(
        publisher_id => $publisherID,
        payor_id     => $payorID,
    );
}

sub _lookupStatementPublisherAccount {
    my ( $self, $publisherID, $payorID, $indirectPublisherID ) = @_;
    return RPS::DB::Item::PublisherIndirectBalanceAccount->Lookup(
        publisher_id          => $publisherID,
        payor_id              => $payorID,
        indirect_publisher_id => $indirectPublisherID
    );
}

sub _createStatementPublisherAccount {
    my ( $self, $publisherID, $payorID, $indirectPublisherID ) = @_;
    return RPS::DB::Item::PublisherIndirectBalanceAccount->Create(
        publisher_id          => $publisherID,
        payor_id              => $payorID,
        indirect_publisher_id => $indirectPublisherID,
    );
}

sub _getStatementTransactionItemsByStatementID {
    my ( $self, $statementID ) = @_;
    return RPS::DB::Item::MechanicalStatementTransaction->GetByMechanicalStatementID($statementID);
}

sub _getStatementPublisherTransactionItems {
    my ( $self, $statementID, $publisherID ) = @_;

    return RPS::DB::Item::MechanicalStatementPublisherTransaction->GetByMechanicalStatementAndPublisherID( $statementID, $publisherID );
}

sub _publisherIDFromStatementTrackItem {
    my ( $self, $trackItem ) = @_;
    return $trackItem->publisher_id;
}

sub _publisherIDFromTrackLicense {
    my ( $self, $trackLicense ) = @_;
    return $trackLicense->publisher_id;
}

sub _publisherIDFromStatementItem {
    my ( $self, $statement ) = @_;
    return $statement->publisher_id();
}

sub _publisherIDFromStatementPublisher {
    my ( $self, $statementPublisher ) = @_;
    return $statementPublisher->publisher_id();
}

sub _idFromTrackLicense {
    my ( $self, $trackLicense ) = @_;
    return $trackLicense->track_license_id();
}

sub _idFromStatementItem {
    my ( $self, $statementItem ) = @_;
    return $statementItem->mechanical_statement_item_id();
}

sub _idFromStatement {
    my ( $self, $statement ) = @_;
    return $statement->mechanical_statement_id();
}

sub _publisherIDFromStatement {
    my ( $self, $statement ) = @_;
    return $statement->publisher_id();
}

sub _idFromStatementLicense {
    my ( $self, $statementLicense ) = @_;
    return $statementLicense->mechanical_statement_license_id();
}

sub _lookupPublisherTrackCrossedLicenseAccount {
    my ( $self, $publisherID, $trackID, $payorID ) = @_;

    return RPS::DB::Item::PublisherTrackCrossedLicenseAccount->Lookup(
        publisher_id => $publisherID,
        track_id     => $trackID,
        payor_id     => $payorID,
    );
}

sub _createPublisherTrackCrossedLicenseAccount {
    my ( $self, $publisherID, $trackID, $payorID, $accountID ) = @_;

    return RPS::DB::Item::PublisherTrackCrossedLicenseAccount->Create(
        publisher_id       => $publisherID,
        track_id           => $trackID,
        payor_id           => $payorID,
        finance_account_id => $accountID,
    );
}

sub _getStatementCrossedLicenseTransactions {
    my ( $self, $statementID, $publisherID, $trackID ) = @_;

    return RPS::DB::Item::MechanicalStatementCrossedLicenseTransaction->GetByMechanicalStatementIDPublisherIDTrackID( $statementID,
        $publisherID, $trackID );
}

sub _idFromStatementLicenseItem {
    my ( $self, $licenseItem ) = @_;
    return $licenseItem->mechanical_statement_license_id();
}

sub _trackLicenseIDFromStatementLicenseItem {
    my ( $self, $licenseItem ) = @_;
    return $licenseItem->track_license_id();
}

sub _getStatementLicenseTransactionsByStatementLicenseID {
    my ( $self, $statementLicenseID ) = @_;
    return RPS::DB::Item::MechanicalStatementLicenseTransaction->GetByMechanicalStatementLicenseID($statementLicenseID);
}

sub _createStatementLicenseTransaction {
    my ( $self, $licenseItemID ) = @_;
    return RPS::DB::Item::MechanicalStatementLicenseTransaction->Create( 'mechanical_statement_license_id' => $licenseItemID, );
}

sub _getAllCommittedLicenseReservesByTrackLicenseID {
    my ( $self, $trackLicenseID ) = @_;
    return RPS::DB::Item::LicenseReserve->GetAllCommittedByTrackLicenseID($trackLicenseID);
}

sub _createLicenseReserveRunItem {
    my ( $self, $reserve ) = @_;
    return RPS::DB::Item::LicenseReserveRun->Create(
        license_reserve_id => $reserve->license_reserve_id,
        mechanical_run_id  => $self->_runID(),
    );
}

sub _getAllMechanicalCarryoverByTrackLicenseID {
    my ( $self, $trackLicenseID ) = @_;
    return RPS::DB::Item::MechanicalCarryover->GetAllByTrackLicenseID($trackLicenseID);
}

sub _createMechanicalRunCarryover {
    my ( $self, $carryover ) = @_;

    my $mechanicalRunCarryoverItem = RPS::DB::Item::MechanicalRunCarryover->Create(
        mechanical_carryover_id => $carryover->mechanical_carryover_id,
        mechanical_run_id       => $self->_runID(),
    );
}

sub _getLicensesForPublisherStatementWithTrackAndRegion {
    my ( $self, $trackID, $regionID, $startDate, $endDate, $publisherID ) = @_;
    return RPS::DB::Item::TrackLicense->GetLicensesForPublisherStatementWithTrackAndRegion( $trackID, $regionID, $startDate, $endDate,
        $publisherID, $self->_payorID() );
}

sub _getPaidSaleRunMapForLicense {
    my ( $self, $license ) = @_;

    return RPS::DB::Item::SaleRunMap->GetPaidUSMechanicalsWithTrackLicense( $license->track_license_id );
}

sub _lookupMechanicalStatementItem {
    my ( $self, $statementItemID ) = @_;
    return RPS::DB::Item::MechanicalStatementItem->Lookup( mechanical_statement_item_id => $statementItemID );
}

sub _getLastStatementAdjustmentItem {
    my ( $self, $statementItemID ) = @_;
    return RPS::DB::Item::MechanicalStatementAdjustmentItem->GetLastStatementAdjustment($statementItemID);
}

sub _idFromStatementAdjustmentItem {
    my ( $self, $lastAdjustment ) = @_;
    return $lastAdjustment->mechanical_statement_adjustment_item_id;
}

sub _idFromRunItem {
    my ( $self, $run ) = @_;
    return $run->mechanical_run_id;
}

sub _createStatementAdjustmentItem {
    my ( $self, $license, $originalStatementItemID, $lastAdjustmentID, $adjustmentAmount, $total ) = @_;

    return RPS::DB::Item::MechanicalStatementAdjustmentItem->Create(
        mechanical_statement_id                          => $self->_statementID(),
        track_license_id                                 => $license->track_license_id(),
        original_mechanical_statement_item_id            => $originalStatementItemID,
        previous_mechanical_statement_adjustment_item_id => $lastAdjustmentID,
        amount                                           => $adjustmentAmount,
        new_total                                        => $total,
        adjustment_type_code =>
          RPS::DB::Item::MechanicalStatementAdjustmentItem::kAdjustmentTypeCCompNewLicense,    #!!! is this really accurate?
    );
}

sub _createStatementPublisher {
    my ( $self, $publisherID ) = @_;

    return RPS::DB::Item::MechanicalStatementPublisher->Create(
        mechanical_statement_id => $self->_statementID(),
        publisher_id            => $publisherID,
    );
}

sub _getStatementPublisherFromAccount {
    my ( $self, $account ) = @_;
    my $publisherID = $account->publisher_id;
    my $publisher;

    my $statementPublishers =
      RPS::DB::Item::MechanicalStatementPublisher->GetByMechanicalStatementAndPublisherID( $self->_statementID(), $publisherID );
    while ( my $statementPublisher = $statementPublishers->next() ) {
        $publisher = $statementPublisher;
    }

    if ( !$publisher ) {
        $publisher = $self->_createStatementPublisher($publisherID);
    }

    return $publisher;
}

sub _getSubPublisherIDs {
    my ( $self, $statementID ) = @_;

    #   my @ids = RPS::DB::Item::MechanicalStatementPublisherTransaction->GetSubPublisherIDs($statementID);
    my @ids;
    my $allPublishers = RPS::DB::Item::MechanicalStatementPublisher->GetByMechanicalStatementID($statementID);
    while ( my $p = $allPublishers->next() ) {
        push @ids, $p->publisher_id;
    }

    return @ids;
}

sub _getPublisherStatement {
    my ( $self, $statementID, $publisherID ) = @_;

    my $publisherStatement;

    $publisherStatement =
      RPS::DB::Item::MechanicalStatementPublisher->Lookup( mechanical_statement_id => $statementID, publisher_id => $publisherID );

    return $publisherStatement;
}

sub _getIndirectAccountByPayorIndirectPublisherID {
    my ( $self, $payorID, $publisherID ) = @_;
    my $indirectAccounts = RPS::DB::Item::PublisherIndirectBalanceAccount->GetByPayorIndirectPublisherID( $payorID, $publisherID );

    return $indirectAccounts;
}

sub _createStatementTrack {
    my ( $self, $publisherID, $trackID, $albumID, $songTitle ) = @_;
    return RPS::DB::Item::MechanicalStatementTrack->Create(
        mechanical_statement_id => $self->_statementID(),
        publisher_id            => $publisherID,
        track_id                => $trackID,
        album_id                => $albumID,
        song_title              => $songTitle,
    );
}

sub _createStatementCrossedLicenseTransaction {
    my ( $self, $statementLicense, $publisherID, $trackID, $pendingTrans ) = @_;

    return RPS::DB::Item::MechanicalStatementCrossedLicenseTransaction->Create(

        #mechanical_statement_license_id => $statementLicense->mechanical_statement_license_id,
        mechanical_statement_id => $self->_statementID(),
        publisher_id            => $publisherID,
        track_id                => $trackID,
        amount                  => $pendingTrans->amount,
        memo                    => $pendingTrans->memo,
        check_number            => $pendingTrans->check_number,
        pending_transaction_id  => $pendingTrans->pending_transaction_id,
        transaction_date        => $pendingTrans->transaction_date,
        type_code               => $pendingTrans->type_code,
    );
}

sub _createStatementTransactionFromPendingTransaction {
    my ( $self, $pendingTrans ) = @_;
    return RPS::DB::Item::MechanicalStatementTransaction->Create(
        mechanical_statement_id => $self->_statementID(),
        amount                  => $pendingTrans->amount(),
        memo                    => $pendingTrans->memo(),
        check_number            => $pendingTrans->check_number(),
        pending_transaction_id  => $pendingTrans->pending_transaction_id(),
        transaction_date        => $pendingTrans->transaction_date(),
        type_code               => $pendingTrans->type_code(),
    );
}

sub _createPublisherStatementTransactionFromPendingTransaction {
    my ( $self, $pendingTrans, $account ) = @_;
    return RPS::DB::Item::MechanicalStatementPublisherTransaction->Create(
        mechanical_statement_id => $self->_statementID(),
        publisher_id            => $account->publisher_id(),
        amount                  => $pendingTrans->amount(),
        memo                    => $pendingTrans->memo(),
        check_number            => $pendingTrans->check_number(),
        pending_transaction_id  => $pendingTrans->pending_transaction_id(),
        transaction_date        => $pendingTrans->transaction_date(),
        type_code               => $pendingTrans->type_code(),
    );
}

sub _getLicensesByTrackIDAndDate {
    my ( $self, $trackID, $startDate, $endDate ) = @_;
    return RPS::DB::Item::TrackLicense->GetLicensesByTrackIDAndDate( $trackID, $startDate, $endDate );
}

sub _getLicensesByTrackID {
    my ( $self, $trackID ) = @_;
    return RPS::DB::Item::TrackLicense->GetLicensesByTrackID($trackID);
}

sub _testAlreadyPaidSaleWithLicense {
    my ( $self, $sale, $trackLicense ) = @_;

    if ( $self->{_RSD7859} ) { 
        my $paidSaleMap = $self->{_paidSaleMap};
        return $paidSaleMap->{$sale->sale_id}{$trackLicense->track_license_id};
    }
    return RPS::DB::Item::SaleRunMap->HavePaidUSMechanicalsForSaleWithTrackLicense( $sale->sale_id, $trackLicense->track_license_id );
}

sub _getStatementDBItem {
    my ($self) = @_;

    my $statement = RPS::DB::Item::MechanicalStatement->Lookup( mechanical_statement_id => $self->{_statementID} );
    return $statement;
}

sub _runType {
    my ($self) = @_;
    return RPS::DB::Item::SaleRunMap::kRunTypeMechanical;
}

sub _getRunDBItem {
    my ($self) = @_;

    my $statement = $self->_getStatementDBItem();
    my $runID     = $statement->mechanical_run_id;
    my $run       = RPS::DB::Item::MechanicalRun->Lookup( mechanical_run_id => $runID );
    return $run;
}

sub _getSaleIDs {
    my ($self) = @_;

    # Read the sales to process from the SalePublisherMap table
    #
    my $statement = $self->_getStatementDBItem();

    return RPS::DB::Item::SalePublisherMap->GetPublisherMappedSaleIDs( $statement->publisher_id, $statement->mechanical_run_id );
}

# We don't want to create log entries for DIGITAL sales outside of CA and US.
#
sub _createRetentionLogEntry {
    my ( $self, $sale, $trackID, $trackLicenseID, $share ) = @_;

    my $product = $self->_getProduct( $sale->product_id );

    if ( $self->_productIsDigital($product) ) {
        if (   'US' ne $sale->country_code
            && 'CA' ne $sale->country_code ) {
            return;
        }
    }

    return $self->SUPER::_createRetentionLogEntry( $sale, $trackID, $trackLicenseID, $share );
}

sub _getControlledCompContractByAlbumID {
    my ( $self, $albumID ) = @_;
    return RPS::DB::Item::AlbumContract->GetCComp($albumID);
}

sub _trackIsExemptFromMechanicals {
    my ( $self, $trackID ) = @_;
    assert($trackID);

    my $track = $self->_getTrack($trackID);
    assert($track);

    return $track->mechanical_exempt;
}

sub _findMatchingLicensesFast {
    my ( $self, $sale ) = @_;
    my $saleID = $sale->sale_id;
    my $licenses = $self->{_saleLicenseMap}{$saleID};

    my @lArray = split(',', $licenses);

    my %_fastLicenses;  # used for verification testing only
    my ( $legacyTime, $legacyLicenses, $t2 );
    if ( $self->{_RSD7859_VERIFY} ) {
        # verify matching licenses returned via the legacy code and compare
        # to licenses returned using the Fast method.

        # TEST - do legacy lookup (only for comparison purposes; we'll use the Fast method for
        # actual results
        my $t0 = Time::HiRes::gettimeofday();
        my $_licenses = $self->_findMatchingLicenses($sale);
        my $t1 = Time::HiRes::gettimeofday();
        $legacyTime = $t1 - $t0;

        # We're going to compare 'legacyTracks' and 'fastTracks', but need to make sure
        # the licenses are sorted in order to compare them properly..

        my %_legacyLicenses;
        foreach my $license (@$_licenses) {
            $_legacyLicenses{ $license->track_license_id } = 1;
        }

        $legacyLicenses = join(",", (sort { $a <=> $b } keys %_legacyLicenses ) );
        $t2 = Time::HiRes::gettimeofday();
    }

    my @trackLicenses;
    foreach my $licenseID (@lArray) {
        my $tl = RPS::DB::Item::TrackLicense->Lookup( track_license_id => $licenseID );

        if ( $tl->publisher_direct && $tl->publisher_id != $self->_publisherID() ) {
            my $_pubID = $tl->publisher_id;
            $self->_report( "_findMatchingLicensesFast: license $licenseID pubID $_pubID not same as " . $self->_publisherID() . ", "
                . "and is marked publisher direct .. skipping", 2 );
            next;
        }

        if ( !$tl->publisher_direct && $tl->publisher_id == $self->_publisherID() && $self->{_isSubPublisher} ) { 
            $self->_report( "_findMatchingLicensesFast: license $licenseID not direct and is for stmt pub " . $self->_publisherID() . ", "
                . "but pub has admin/agent .. skipping", 2 );
            next;
        }

        $_fastLicenses{ $tl->track_license_id } = 1 if ( $self->{_RSD7859_VERIFY} );

        push @trackLicenses, $tl;
    }

    if ( $self->{_RSD7859_VERIFY} ) {

        my $t3 = Time::HiRes::gettimeofday();
        my $fastTime = $t3 - $t2;

        my $fastLicenses = join(",", (sort { $a <=> $b } keys %_fastLicenses ) );

        my $saleID = $sale->sale_id;
        my $pID    = $sale->product_id;
        my $sInfo  = "saleID $saleID prod $pID";
        my $verifyStatus = ( $legacyLicenses eq $fastLicenses ) ? "MATCH: licenses($fastLicenses)" : "MISMATCH: legacy($legacyLicenses) fast($fastLicenses)";

        $self->_report(" >> FAST delta ". ($fastTime - $legacyTime) . " second(s)  $sInfo results $verifyStatus", 2 );

    }

    return \@trackLicenses;
}

sub _readSaleLicenseMap {
    my ( $self, $saleIDs ) = @_;
    $self->{_paidSaleMap} = RPS::DB::Item::SaleLicenseMap->GetLicenseMappedSaleIDs( $self->_runID(), $saleIDs );
    $self->_report( "Done initializing Paid Sale Map");
} # _readSaleLicenseMap

sub _readSalePublisherLicenseMap {
    my ( $self, $statement ) = @_;

    $self->_report( "Initializing SalePublisherLicenseMap for publisher ". $statement->publisher_id . " ...");
    $self->{_saleLicenseMap} = RPS::DB::Item::SalePublisherLicenseMap->GetPublisherMappedSaleIDs( $statement->publisher_id, $self->_runID() );

    $self->_report( "Done initializing Sale License Map");
} # _readSalePublisherLicenseMap

sub _isASubPublisher {
    my ( $self, $statement ) = @_;
    my $o = RPS::DB::Item::Publisher->Lookup( publisher_id => $statement->publisher_id );
    return  1 if ( $o->admin_id || $o->agent_id );
}
1;
