#------------------------------------------------------------
# Copyright (C) 2009 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package BookPub::Tracker::Period;

use strict;
use warnings;

use lib '/app/tools/common/lib';
use Common::Client;
use Common::Util;
use base 'Common::FormObject';

use lib '/app/tools/bookpub/lib';
use BookPub::DB::Item::File;
use BookPub::DB::Item::Period;
use BookPub::DB::Item::InputConversionRate;

sub _init {
    my ( $self, %args ) = @_;

    $self->SUPER::_init(%args);

    my %properties;
    if ( $args{_dbItem} ) {
        $self->_propertiesFromDBItem( \%properties, $args{_dbItem} );
    } elsif ( defined $args{periodID} ) {
        $self->_propertiesFromDB( \%properties, $args{periodID} );
    }

    my $rval = $self->_initProperties( \%properties );

    return $rval;
}

sub _propertiesFromDB {
    my ( $self, $hrProperties, $periodID ) = @_;

    $periodID = 0 unless $periodID;

    my $dbItem = BookPub::DB::Item::Period->Lookup( period_id => $periodID );
    if ( !$periodID && !$dbItem ) {

        # This is a bit unusual. We want to create a new period 0, and actually save it.
        #
        $self->_defaultProperties($hrProperties);
        $self->save();

        $self->_propertiesFromDB( $hrProperties, $periodID );
    } else {
        $self->_propertiesFromDBItem( $hrProperties, $dbItem );
    }
}

sub _defaultProperties {
    my ( $self, $hrProperties ) = @_;

    $hrProperties->{period_id} = 0;
}

sub _propertiesFromDBItem {
    my ( $self, $hrProperties, $dbItem ) = @_;

    # Save a reference to the dbItem we used, so we can tell later if this object
    # exists in the database already...
    #
    $self->{_dbItem} = $dbItem;

    $hrProperties->{period_id}  = $dbItem->period_id;
    $hrProperties->{name}       = $dbItem->name;
    $hrProperties->{start_date} = $dbItem->start_date;
    $hrProperties->{end_date}   = $dbItem->end_date;
    $hrProperties->{notes}      = $dbItem->notes;

    $hrProperties->{date_created}  = $dbItem->date_created;
    $hrProperties->{date_modified} = $dbItem->date_modified;
}

sub _initProperties {
    my ( $self, $props ) = @_;

    my $periodID = $props->{period_id};

    $self->{PeriodID}  = $periodID;
    $self->{Name}      = Common::FormObject::Scalar::String->new( value => $props->{name} );
    $self->{StartDate} = Common::FormObject::Scalar::Date->new( value => $props->{start_date} );
    $self->{EndDate}   = Common::FormObject::Scalar::Date->new( value => $props->{end_date} );
    $self->{Notes}     = Common::FormObject::Scalar::String->new( value => $props->{notes} );

    $self->{CreatedDate}  = Common::FormObject::Scalar::DateTime->new( value => $props->{date_created},  readOnly => 1 );
    $self->{ModifiedDate} = Common::FormObject::Scalar::DateTime->new( value => $props->{date_modified}, readOnly => 1 );

    # Let's add some summary information if we're not in the open period
    if ($periodID) {

        my $currencyCode  = Common::Client::Current()->Locale()->currencyFormat()->currencyCode();
        my $periodSummary = BookPub::DB::Item::File->GetSummaryByPeriodID( $periodID, $currencyCode );
        my $revenue       = $periodSummary->{revenue};
        my $units         = $periodSummary->{units};
        my $fileCount     = $periodSummary->{count};

        # Now we have to add in the converted amounts for the files in a foreign currency.
        my $foreignFiles = BookPub::DB::Item::File->GetAllForeignByPeriodID( $periodID, $currencyCode );

        while ( $foreignFiles->hasNext() ) {
            my $foreignFile = $foreignFiles->next();
            my $fileRevenue = 0;

            my $inputRates = BookPub::DB::Item::InputConversionRate->GetAllByFileID( $foreignFile->{file_id} );
            if ( $inputRates->size ) {
                while ( my $item = $inputRates->next() ) {

                    # Don't include revenue due to alternate rate conversions
                    #
                    $fileRevenue += $item->revenue * $item->conversion_rate if ( !$item->is_alternate );
                }
            }

            $fileCount++;
            $units += $foreignFile->{units};
            $revenue += Common::Util::formatFixedPoint( $fileRevenue, 2 );

        }

        $self->{RevenueTotal} = Common::FormObject::Scalar::Money->new( value => $revenue );
        $self->{UnitTotal} = Common::FormObject::Scalar::Integer->new( value => $units );
        $self->{FileCount} = Common::FormObject::Scalar::Integer->new( value => $fileCount );
    }

    # We'll need to know the 'max' period.
    #
    my $maxPeriodID = BookPub::DB::Item::Period->GetMaxPeriodID();

    my $prevPeriod;
    my $nextPeriod;
    if ( 0 == $props->{period_id} ) {

        # This is the current period.
        #
        $prevPeriod = $maxPeriodID;
    }
    elsif ( $maxPeriodID == $props->{period_id} ) {
        $nextPeriod = 0;
        if ( $props->{period_id} > 1 ) {
            $prevPeriod = $props->{period_id} - 1;
        }
    }
    else {
        $nextPeriod = $props->{period_id} + 1;
        $prevPeriod = $props->{period_id} - 1;
    }

    $self->{PrevPeriodID} = $prevPeriod;
    $self->{NextPeriodID} = $nextPeriod;

    return $self;
}

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

    my $dbItem = $self->{_dbItem};

    if ( !$dbItem ) {
        $dbItem = BookPub::DB::Item::Period->Create( period_id => 0 );
        $dbItem->date_created( Common::DB::Item::kDateTimeNow() );
    }

    my $initialPeriod = BookPub::DB::Item::Period->Lookup( period_id => 0 );

    if ($initialPeriod) {

        # We don't want to try to set these if we are creating the first period ever for this client.
        #
        $dbItem->period_id( $self->PeriodID() );
        $dbItem->name( $self->Name() );
        $dbItem->start_date( $self->StartDate() );
        $dbItem->end_date( $self->EndDate() );
        $dbItem->date_modified( Common::DB::Item::kDateTimeNow() );
        $dbItem->notes( $self->Notes() );
    }

    $dbItem->save();
    $self->_init( _dbItem => $dbItem );

    return 1;
}

1;
