#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package Raptor::Tracker::Command::ClosePeriod;
use strict;
use warnings;

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

use lib '/app/tools/rps/lib';
use RPS::DB::Item::ClientOptions;
use RPS::File::File;

use lib '/app/tools/raptor/lib';
use Raptor::Tracker::Command::Main;
use Raptor::Tracker::Job::BillablePeriodReport;
use Raptor::Tracker::Job::DumpRoyaltyReport;

use Raptor::Command;
use base 'Raptor::Tracker::Command::Base';

use lib '/app/tools/job/lib';
use Job::Job;

sub cmd  { return "close"; }
sub area { return "tracker"; }

use constant kTemplate => '/app/tools/raptor/templates/tracker.xsl';

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

    # Give any inherited methods the first crack at this.
    # (This checks for login and basic access permissions).
    #
    my $response = $self->SUPER::execute();
    return $response if $response;

    my $period      = new Period::RoyaltyPeriod();
    my $periodParam = $self->getParam('period');
    if ( !$periodParam ) {
        $period->LoadCurrent();
    } else {
        $period->Load( period_id => $periodParam );
    }

    # you can only close the current 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($period);
            if ( $new_period_id && $new_period_id > 0 ) {

                # Create the new job, and put it in the queue.
                #
                my $jobArgs = Raptor::Tracker::Job::DumpRoyaltyReport->new( periodID => $new_period_id );
                my $job = $jobArgs->enqueue();

                # Create the billable period report job (if the client option is set), and put it in the queue.
                #
                if ( RPS::DB::Item::ClientOptions->Get( 'billable_period_report' ) ) {
                    $jobArgs = Raptor::Tracker::Job::BillablePeriodReport->new( periodID => $new_period_id );
                    $job = $jobArgs->enqueue();
                }

                return RSApache::Response::Redirect->new("/app/tracker?period=$new_period_id");
            } else {

                #                $self->addMessageXML(type => "error", code => $self->ErrorCode);
            }

            return RSApache::Response::XSLT->new( $self->{xml}, kTemplate );
        } 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.
        }
    }

    $self->doFileListing($period);
    $self->{xml}{Report}{Period} = $period->GetObjectXML();
    $self->setExceptionsFileStatus();

    $response = RSApache::Response::XSLT->new( $self->{xml}, kTemplate );

    return $response;
}

sub closePeriod {
    my ( $self, $oldPeriod ) = @_;
    my $today = Common::Util::today();

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

    if ( !$new_period->PeriodID ) {
        $self->addMessageXML( type => 'error', code => 'close_period_failed' );

        #$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->addMessageXML( type => 'error', code => 'close_period_failed' );

        #        $self->ErrorCode("close_period_failed");
        return undef;
    }

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

    return $new_period->PeriodID;
}

1;
