#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package RPS::Publisher::Command::US::Edit;

use lib '/app/tools/common/lib';
use RSApache::Response::XSLT;

use lib '/app/tools/rps/lib';
use RPS::Publisher::US::EditForm;
use RPS::Publisher::Command::US::Show;
use RPS::DB::Item::MechanicalRun;
use RPS::DB::Item::Publisher;
use RPS::DB::Item::PublisherAccount;
use RPS::DB::Item::FinanceTransaction;

use RPS::Publisher::US::PublisherStatementRecipient;

use base 'RPS::Publisher::Command::BaseEdit';

use constant kMaxRecipients => 5;
use constant kRecipientPostfix => '_Alt';

sub area { return "publisher"; }

sub _template    { return "/app/tools/rps/templates/publisher/edit.xsl"; }
sub _editForm    { return "RPS::Publisher::US::EditForm"; }
sub _editCommand { return "RPS::Publisher::Command::US::Edit"; }
sub _showCommand { return "RPS::Publisher::Command::US::Show"; }

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

    # If there are any "open" (completed, running, waiting to run, waiting to commit) runs
    # that include this publisher, we don't want to allow any changes.
    my $openRuns = 0;
    $openRuns = RPS::DB::Item::MechanicalRun->GetOpenRunCountForPublisher($publisherID);

    return $openRuns;
}

sub _canBeDeleted {
    my ($self, $id) = @_;

    return 0 unless $id && $id =~ /^\d+$/;

    my $oPublisher = RPS::DB::Item::Publisher->Lookup( publisher_id => $id );
    return $self->_isActionAllowed($oPublisher);
}

sub _isActionAllowed {
    my ($self, $oPublisher) = @_;

    my $restricted = 0;
    $restricted += $self->_isAdminOrAgent($oPublisher);
    $restricted += $self->_hasAttachedLicenses($oPublisher);
    $restricted += $self->_hasRunActivity($oPublisher);
    $restricted += $self->_hasPendingOrHistoryTransactions($oPublisher);

    return !$restricted;
}

sub _isAdminOrAgent {
    my ($self, $oPublisher) = @_;

    my $res = 0;

    my $oCollection = RPS::DB::Item::Publisher->GetByAdminID( $oPublisher->publisher_id );
    while ( my $oItem = $oCollection->next() ) {
        $res += $oItem->publisher_id;
        last;
    }

    $oCollection = RPS::DB::Item::Publisher->GetByAgentID( $oPublisher->publisher_id );
    while ( my $oItem = $oCollection->next() ) {
        $res += $oItem->publisher_id;
        last;
    }

    return $res;
}

sub _hasAttachedLicenses {
    my ($self, $oPublisher) = @_;

    my $res = 0;

    my $oCollection = RPS::DB::Item::Publisher->GetAllWithLicenses( $oPublisher->publisher_id );
    while ( my $oItem = $oCollection->next() ) {
        $res += $oItem->publisher_id;
        last;
    }

    return $res;
}

sub _hasRunActivity {
    my ($self, $oPublisher) = @_;

    # check for any run activity
    return RPS::DB::Item::Publisher->HasRunActivity( $oPublisher->publisher_id );
}

sub _hasPendingOrHistoryTransactions {
    my ($self, $oPublisher) = @_;

    my $res = 0;

    # pending
    my $oCollection = RPS::DB::Item::PublisherAccount->GetAllWithPendingTransactions(
        undef, $oPublisher->publisher_id
    );
    while ( my $oItem = $oCollection->next() ) {
        $res += $oItem->finance_account_id;
        last;
    }

    # history
    $oCollection = RPS::DB::Item::FinanceTransaction->GetTransactionsHistoryByPublisher( $oPublisher->publisher_id );
    while ( my $oItem = $oCollection->next() ) {
        $res += $oItem->finance_account_id;
        last;
    }

    return $res;
}

sub _assignCGIParams {
    my ($self, $form) = @_;

    my $payeeStatus      = $form->assignCGIParams( 'Form', $self->getParams() );
    my $recipientsStatus = $self->_assignCGIParamsRecipients($form);
    return $payeeStatus && $recipientsStatus;
}

sub _validateForm {
    my ($self, $form) = @_;

    my $payeeStatus      = $form->validate();
    my $recipientsStatus = $self->_recipientPostValidate($form);

    return $payeeStatus && $recipientsStatus;
}

sub _assignCGIParamsRecipients {
    my ($self, $form) = @_;

    my $subFormPrefix            = 'StatementRecipient';
    my $publisherIDAttr          = $subFormPrefix . '_PublisherID';
    my $statementRecipientIDAttr = $subFormPrefix . '_StatementRecipientID';
    my $deleteRecipientAttr      = $subFormPrefix . '_WaitingToDelete';

    my $status = 0;
    my $liveItems = 0;
    my @newRecipientsList;
    foreach my $i ( 1 .. kMaxRecipients ) {
        my $hParams = $self->_getSingleRecipientParams(kRecipientPostfix . $i);
        next unless grep {$_} values %$hParams;

        # The '_StatementRecipientID' attribute can be present if we are updating an existing recipient,
        # or empty if this is a new recipient.
        my $recipientID = exists $hParams->{$statementRecipientIDAttr}
            ? $hParams->{$statementRecipientIDAttr}
            : 0;

        # The '_WaitingToDelete' attribute only exists when we try to delete a recipient (existing or non-existing).
        if ( exists $hParams->{$deleteRecipientAttr} && $hParams->{$deleteRecipientAttr} ) {
            # Check if a non-existing item is pending removal
            $recipientID = $hParams->{$deleteRecipientAttr} =~ /^\d+$/
                ? $hParams->{$deleteRecipientAttr}
                : next;
        }

        $liveItems++;
        $hParams->{$publisherIDAttr} = $form->getPublisherID();

        my ($oRecipient) = grep { $_->StatementRecipientID eq $recipientID } @{ $form->getPublisherRecipients() };
        $oRecipient = RPS::Publisher::US::PublisherStatementRecipient->new() unless $oRecipient;
        if ( $oRecipient->assignCGIParams($subFormPrefix, $hParams) && $oRecipient->validate() ) {
            $status++;
        }

        push @newRecipientsList, $oRecipient;
    }

    # overwrite recipients
    $form->{PublisherRecipients} = \@newRecipientsList;

    return $liveItems == $status ? 1 : 0;
}

sub _getSingleRecipientParams {
    my ($self, $postfix) = @_;

    my %params;
    while ( my($k, $v) = each %{ $self->getParams() } ) {
        next unless $k =~ /$postfix$/;
        $k =~ s/$postfix$//;
        $params{$k} = $v;
    }

    return \%params;
}

sub _recipientPostValidate {
    my ($self, $form) = @_;

    $valid = 1;

    # Check E-mails for duplicates including main payee's email.
    my $hEmails = {};
    for ( $form->{Publisher}->Email(), $form->{Publisher}->OrigEmail() ) {
        $hEmails->{$_} = 1 if $_;
    }

    # Additional payee recipients' E-mails
    foreach my $oRecipient ( @{ $form->getPublisherRecipients() } ) {
        my $email = $oRecipient->Email();
        if ( exists $hEmails->{$email} ) {
            $oRecipient->{Email}->setError( Common::FormObject::kErrFieldDuplicate );
            $valid = 0;
        }
        $hEmails->{ $oRecipient->Email }++;

        # Harry Fox Agency is not supported at this time
        if ( $email =~ /harryfox\.com$/i ) {
            $oRecipient->{Email}->setError( Common::FormObject::kErrEmailUnsupported );
            $valid = 0;
        }
    }

    return $valid;
}

sub _saveStatementRecipients {
    my ($self, $form) = @_;

    foreach my $oRecipient ( @{ $form->getPublisherRecipients() } ) {
        next if $oRecipient->WaitingToDelete;
        $oRecipient->save();
    }

    return 1;
}

sub _deletePendingStatementRecipients {
    my ($self, $form) = @_;

    foreach my $oRecipient ( @{ $form->getPublisherRecipients() } ) {
        next unless ( $oRecipient->WaitingToDelete && $oRecipient->StatementRecipientID );
        $oRecipient->delete();
    }

    return 1;
}



1;

