#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2011 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------

package RPS::Report::Dynamic::Payee::Publishers;

use strict;
use warnings;
use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::Assert;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::Affiliate;
use RPS::DB::Item::Payor;
use RPS::DB::Item::FinanceTransaction;
use RPS::DB::Item::PendingTransaction;

use base 'RPS::Report::Dynamic::Payee::Base';

# defined at the end of this file
#
sub _ParamClass { 'RPS::Report::Dynamic::Payee::Publishers::Parameters'; }

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

    my $cols = [];

    push( @$cols, $self->_getNameColumnHash('publisher', 'publisher' ) );
    push( @$cols, $self->_getNameColumnHash('client-account-no', 'client_account_no' ) );
    push( @$cols, $self->_getNameColumnHash('status', 'status' ) );
    push( @$cols, $self->_getNameColumnHash('address-1', 'address_1' ) );
    push( @$cols, $self->_getNameColumnHash('address-2', 'address_2' ) );
    push( @$cols, $self->_getNameColumnHash('address-3', 'address_3' ) );
    push( @$cols, $self->_getNameColumnHash('city', 'city' ) );
    push( @$cols, $self->_getNameColumnHash('state-province', 'state' ) );
    push( @$cols, $self->_getNameColumnHash('zip-postal', 'postal_code' ) );
    push( @$cols, $self->_getNameColumnHash('country', 'country' ) );
    push( @$cols, $self->_getNameColumnHash('email', 'email' ) );
    push( @$cols, $self->_getNameColumnHash('phone', 'phone' ) );
    push( @$cols, $self->_getNameColumnHash('fax', 'fax' ) );
    push( @$cols, $self->_getNameColumnHash('publisher-type', 'publisher_type' ) );
    push( @$cols, $self->_getNameColumnHash('admin', 'admin' ) );
    push( @$cols, $self->_getNameColumnHash('agent', 'agent' ) );
    push( @$cols, $self->_getNameColumnHash('tax-id', 'tax_id' ) );
#    push( @$cols, $self->_getNameColumnHash('affiliation', 'affiliation' ) );
    push @$cols, {
        header => {
            name => 'affiliation',
        },
        column => {
            field => 'affiliate_id',
            method => '_idToAffiliate', 
        }
    };
    push( @$cols, $self->_getNameColumnHash('comments', 'comments' ) );


    push @$cols, {
        header => {
            name => 'publisher-date-created',
        },
        column => {
            field => 'date_created',
            method => '_formatDate',
             excel => 'date:Y-M-D',
        }
    };
    push @$cols, {
        header => {
            name => 'publisher-created-by',
        },
        column => {
            field => 'created_by',
            method => '_userIDToUserName',
        }
    };
    push @$cols, {
        header => {
            name => 'publisher-date-modified',
        },
        column => {
            field => 'date_modified',
            method => '_formatDate',
            excel => 'date:Y-M-D',
        }
    };
    push @$cols, {
        header => {
            name => 'publisher-modified-by',
        },
        column => {
            field => 'modified_by',
            method => '_userIDToUserName',
        }
    };
    push( @$cols, $self->_getNameColumnHash('rs-publisher-id', 'publisher_id' ) );

   
    return $cols;
}

sub _getEmptyColumnHash 
{
    my ($self, $name) = @_;
    return {
        header => { name => $name, },
        column => { value => '', },
    };
}


my $gAffiliateCache;
sub _idToAffiliate
{
    my ($self, %args) = @_;
    my $rowItem = $args{row};
    my $fieldName = $args{field};

    my $id = $rowItem->$fieldName();

    my $affiliate;
    if ($id)
    {
        if (! $gAffiliateCache)
        {
            $gAffiliateCache = {};
            my $all = RPS::DB::Item::Affiliate->GetAll();
            while (my $data = $all->next())
            {
                $gAffiliateCache->{ $data->affiliate_id() } = $data->name();
            }
        }

        $affiliate = $gAffiliateCache->{$id};
    }

    return $affiliate;
}


# Overriding this to fetch and return any transactions (if requested and there are any).
#
#sub _nextReportLineData
#{
#    my ($self) = @_;
#
#    # Are we still sending out transactions from the last Publisher?
#    #
#    if (defined $self->{_transactionList} && 0 != scalar @{$self->{_transactionList}})
#    {
#        return $self->_nextReportLineWithTransaction();
#    }
#
#    $self->{_currentLine} = $self->SUPER::_nextReportLineData();
#
#
#    # If we're supposed to be reporting transactions, first try and fetch all of them.
#    # If we got some, then start returning lines with transactions attached.
#    # Otherwise, just return the latest line.
#    #
#    if( $self->{_currentLine} && ($self->_showProcessed() || $self->_showUnprocessed() ) )
#    {
#        $self->_fetchAllTransactions();
#
#
#        # Return the line with transactions, if there were any.
#        #
#        if (defined $self->{_transactionList} && 0 != scalar @{$self->{_transactionList}})
#        {
#            return $self->_nextReportLineWithTransaction();
#        }
#    }
#
#
#    return $self->{_currentLine};
#}
#
#
#my %gTransactionTypes = (
#    RPS::DB::Item::FinanceTransaction::kTypeOpeningBalance()    => 'opening balance',
#    RPS::DB::Item::FinanceTransaction::kTypeAdjustment()        => 'adjustment',
#    RPS::DB::Item::FinanceTransaction::kTypeAdvance()           => 'advance',
#    RPS::DB::Item::FinanceTransaction::kTypePayment()           => 'payment',
#    RPS::DB::Item::FinanceTransaction::kTypeClosingBalance()    => 'closing balance',
#);
#
## So my strategy here is to go ahead and grab _all_ the transactions from all accounts,
## and stuff that data into an array reference. 
##
#sub _fetchAllTransactions
#{
#    my ($self) = @_;
#
#    # Make sure we're dealing with an empty array.
#    #
#    $self->{_transactionList} = [];
#
#
#    # We'll need our publisher id.
#    # Note that this is either a 'publisher_id' or a 'ca_publisher_id', depending on
#    # what flavor of report we're building, but we use the same key name in the report header.
#    #
#    if (! $self->{_arrayIndex})
#    {
#        $self->_buildArrayIndex();
#    }
#    my $pubID = $self->{_currentLine}->[ $self->{_arrayIndex}{'rs-publisher-id'} ];
#
#    if (! $pubID)
#    {
##        return;
#    }
#
#    # We'll need a bit of abstraction here, since the US and CA publishers have
#    # different account tables.  Happily, the schemas are virtually identical:  Only
#    # the 'publisher id' key and table keys are different.
#    #
#    my $directAccountCollection = $self->_getDirectAccounts($pubID);
#    while (my $directAccount = $directAccountCollection->next())
#    {
#        my $payor = RPS::DB::Item::Payor->Lookup(payor_id => $directAccount->payor_id());
#
#        if ($self->_showProcessed())
#        {
#            # !!! Do we need to contrain this list by date?
#            #
#            my $transactions = RPS::DB::Item::FinanceTransaction->GetAccountTransactions(finance_account_id => $directAccount->finance_account_id());
#            while (my $t = $transactions->next())
#            {
#                push @{$self->{_transactionList}}, $self->_getTransactionHash($payor, $directAccount->min_payment(), $t->balance(), $t, 'direct', 'processed');
#            }
#        }
#        
#        if ($self->_showUnprocessed())
#        {
#            my $transactions = RPS::DB::Item::PendingTransaction->GetAccountTransactions(finance_account_id => $directAccount->finance_account_id());
#            while (my $t = $transactions->next())
#            {
#                push @{$self->{_transactionList}}, $self->_getTransactionHash($payor, $directAccount->min_payment(), '', $t, 'direct', 'pending');
#            }
#        }
#    }
#
#    
#    # Now the same thing with the indirect accounts.
#    #
#    my $indirectAccountCollection = $self->_getIndirectAccounts($pubID);
#    while (my $indirectAccount = $indirectAccountCollection->next())
#    {
#        my $payor = RPS::DB::Item::Payor->Lookup(payor_id => $indirectAccount->payor_id());
#
#        if ($self->_showProcessed())
#        {
#            my $transactions = RPS::DB::Item::FinanceTransaction->GetAccountTransactions(finance_account_id => $indirectAccount->finance_account_id());
#            while (my $t = $transactions->next())
#            {
#                # Note that indirect accounts don't have minimum payments.
#                #
#                push @{$self->{_transactionList}}, $self->_getTransactionHash($payor, '', $t->balance(), $t, 'indirect', 'processed');
#            }
#        }
#        
#        if ($self->_showUnprocessed())
#        {
#            my $transactions = RPS::DB::Item::PendingTransaction->GetAccountTransactions(finance_account_id => $indirectAccount->finance_account_id());
#            while (my $t = $transactions->next())
#            {
#                push @{$self->{_transactionList}}, $self->_getTransactionHash($payor, '', '', $t, 'indirect', 'pending');
#            }
#        }
#    }
#}
#
#
#sub _getDirectAccounts
#{
#    my ($self, $pubID) = @_;
#    assert(0, 'override');
#}
#
#sub _getIndirectAccounts
#{
#    my ($self, $pubID) = @_;
#    assert(0, 'override');
#}
#
#sub _getTransactionHash
#{
#    my ($self, $payor, $minPayment, $balance, $transaction, $type, $status) = @_;
#
#    return {
#        'payor-name'            => $payor->name(),
#        'client-payor-no'       => $payor->client_payor_id(),
#        'payor-status'          => $payor->inactive() ? 'inactive' : 'active',
#        'default-payor'         => $payor->is_default() ? 'yes' : 'no',
#        'minimum-payment'       => $minPayment,
#        'account-type'          => $type,
#        'transaction-status'    => $status,
#        'transaction-type'      => $gTransactionTypes{ $transaction->type_code() },
#        'amount'                => $transaction->amount(),
#        'transaction-date'      => $transaction->transaction_date(),
#        'check-no'              => $transaction->check_number(),
#        'memo'                  => $transaction->memo(),
#        'balance'               => $balance,
#    };
#}
#
#
#sub _nextReportLineWithTransaction
#{
#    my ($self) = @_;
#
#    # Shift the next transaction off the list.
#    # (We want the one from the front of the list, hence shift).
#    #
#    my $transaction = shift @{$self->{_transactionList}};
#
#    # Populate the transaction columns.
#    #
#    # We need to know the array index for each column.
#    # This can shift around depending on what options were selected.
#    # So we'll build a hash that maps column title to array index.
#    #
#    if (! $self->{_arrayIndex})
#    {
#        $self->_buildArrayIndex();
#    }
#
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'payor-name'} ]               = $transaction->{'payor-name'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'client-payor-no'} ]          = $transaction->{'client-payor-no'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'payor-status'} ]             = $transaction->{'payor-status'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'default-payor'} ]            = $transaction->{'default-payor'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'minimum-payment'} ]          = $transaction->{'minimum-payment'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'account-type'} ]             = $transaction->{'account-type'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'transaction-status'} ]       = $transaction->{'transaction-status'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'transaction-type'} ]         = $transaction->{'transaction-type'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'amount'} ]                   = $transaction->{'amount'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'transaction-date'} ]         = $transaction->{'transaction-date'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'check-no'} ]                 = $transaction->{'check-no'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'memo'} ]                     = $transaction->{'memo'};
#    $self->{_currentLine}->[ $self->{_arrayIndex}{'balance'} ]                  = $transaction->{'balance'};
#
#
#    return $self->{_currentLine};
#}


sub _buildArrayIndex
{
    my ($self) = @_;
    $self->{_arrayIndex} = {};

    my $columns = $self->_columns();
    for (my $i = 0; $i < scalar @$columns; $i++)
    {
        my $col = $columns->[$i];

        my $colName = $col->{header}{name};
        assert(! defined $self->{_arrayIndex}{$colName});
        $self->{_arrayIndex}{$colName} = $i;
    }
}



1;

package RPS::Report::Dynamic::Payee::Publishers::Parameters;
use strict;
use warnings;

use lib '/app/tools/common/lib';
use lib '/app/tools/report/lib';
use lib '/app/tools/rps/lib';
use base 'RPS::Report::Dynamic::Payee::Parameters';




1;
