#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2009 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#---------------------------------------------------------------
package BookPub::Sale::Report::PriceExceptions;
use strict;
use warnings;

use File::Path;

use lib '/app/tools/common/lib';
use lib '/app/tools/bookpub/lib';
use BookPub::DB::Item::Service;
use BookPub::Config;
use BookPub::DB::Item::BookFormat;
use BookPub::DB::Item::BookProduct;
use BookPub::DB::Item::File;
use BookPub::DB::Item::Sale::AllPriceExceptionsReport;
use BookPub::DB::Item::PriceType;
use BookPub::DB::Item::PriceTypeQualifier;
use Common::Util;
use Common::Assert;

use base 'BookPub::Sale::Report';

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

    return 'BookPub::Sale::Report::PriceExceptions::Row';
}

sub _seperator {
    my ($self) = @_;
    return "\t";
}

#sub fileName
#{
#    my ($self) = @_;
#    return 'AllExceptions.txt';
#}
#
#sub excelFileName
#{
#    my ($self) = @_;
#    return 'AllExceptions.xls';
#}

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

    if ( !$self->{_excelFilePath} ) {
        my $baseDir = $self->_baseDir();
        $self->{_excelFilePath} = $baseDir . '/' . $self->excelFileName();
    }
    return $self->{_excelFilePath};
}

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

    # Make sure we have a directory to write the final file into.
    #
    my $baseDir = $self->_baseDir();
    if ( !-d $baseDir ) {
        File::Path::mkpath($baseDir) || die "ERROR - make_path failed for $baseDir: $!";
    }

    my $dest_file_path = $self->filePath();
    my $tmp_file_path  = $dest_file_path . '-tmp';

    unless ( open TMP, ">$tmp_file_path" ) {
        die "can't create file $tmp_file_path\n";
    }
    binmode( TMP, ':utf8' );

    # !!! I'm joining 3 tables: file,sale,service.
    # Which DB::Item interface ought to own that?
    # !!! Let's try extending the 'Sale' table to include the extra rows.
    #
    my $sales = $self->_getSales();

    #    my $sales = BookPub::DB::Item::Sale::AllExceptionsReport->ReportQuery();

    my $rowClass = $self->getRowClass();
    my @all_rows = ();

    my $fields = $rowClass->Fields();
    my $header = join( $self->_seperator, @$fields );
    print TMP "$header\n";

    while ( my $sale = $sales->next() ) {
        my $rowObj = $rowClass->new( sale => $sale );

        my @values = ();
        foreach my $fieldName (@$fields) {
            my $value = $rowObj->{$fieldName};
            $value = '' unless defined $value;
            $value =~ s/\s/ /g;
            push @values, $value;
        }

        # Actually output the row.
        # Note that we determine which character to use as a delimeter via a private method.
        #
        print TMP join( $self->_seperator(), @values ) . "\n";

    }

    # now that we have all the rows (hrefs) in an array,
    # let's sort it and write the data to our file.

    close TMP;

    # Just rename the temp file, and we're done.
    #
    `mv $tmp_file_path $dest_file_path`;

    return 1;

}

sub createExcel {
}

###
1;    #
###

package BookPub::Sale::Report::PriceExceptions::Row;
use strict;
use warnings;

use lib '/app/tools/common/lib';
use lib '/app/tools/bookpub/lib';
use BookPub::DB::Item::BookContributor;
use BookPub::DB::Item::Service;
use BookPub::DB::Item::File;
use BookPub::DB::Item::OnixCode;
use BookPub::DB::Item::PriceTypeQualifier;
use BookPub::Config;
use BookPub::Catalog::Imprint;
use BookPub::Matcher::Product;
use Common::Util;
use Common::Assert;
use Common::RSApp;

sub new {
    my ( $class, %args ) = @_;

    my $self = bless {}, $class;
    return $self->_init(%args);
}

# This is a static class method! Invoke like so:
# BookPub::Sale::Report::Royalty::Row->Fields()
#
sub Fields {
    my ($class) = @_;

    my $appRamCache = Common::RSApp::GetRAMCache();

    if ( !$appRamCache->{$class}{Fields} ) {
        my @fields;

        # By using a second private method, we'll be able
        # to use inheritance - This provides a method that
        # subclasses can override or extend.
        #
        $class->_addFields( \@fields );

        $appRamCache->{$class}{Fields} = \@fields;
    }

    return $appRamCache->{$class}{Fields};
}

sub _addFields {
    my ( $self, $fieldArray ) = @_;

    # What we're doing here is determining:
    # - The field order,
    # - The column names (i.e. the header labels)
    # - The accessor method name to provide that data.
    #
    push @$fieldArray, 'file_name';
    push @$fieldArray, 'service';
    push @$fieldArray, 'format_type';
    push @$fieldArray, 'date_begin';
    push @$fieldArray, 'date_end';
    push @$fieldArray, 'isbn13';
    push @$fieldArray, 'isbn10';
    push @$fieldArray, 'service_product_id';
    push @$fieldArray, 'work_id';
    push @$fieldArray, 'title';
    push @$fieldArray, 'subtitle';
    push @$fieldArray, 'author';
    push @$fieldArray, 'units';
    push @$fieldArray, 'revenue';
    push @$fieldArray, 'price_type';
    push @$fieldArray, 'price_type_qualifier';
    push @$fieldArray, 'price_type_qualifier_code';
    push @$fieldArray, 'price_effective_date';
    push @$fieldArray, 'country_code';
    push @$fieldArray, 'currency_code';
    push @$fieldArray, 'price';
    push @$fieldArray, 'reported_currency';
    push @$fieldArray, 'reported_price';
    push @$fieldArray, 'variance_%';
    push @$fieldArray, 'sales_line_num';
    push @$fieldArray, 'status';
}

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

    my $status = "Unapproved";
    if ( $sale->approved ) {
        $status = "Approved";
    }

    my $priceType = "RRP";
    if ( $sale->is_agency eq 'Y' ) {
        $priceType = "Agency";
    }

    my $priceTypeQualifier;
    if ( $sale->price_type_qualifier_id == BookPub::DB::Item::PriceTypeQualifier::kCorporate ) {
        $priceTypeQualifier = "Corporate";
    } elsif ( $sale->price_type_qualifier_id == BookPub::DB::Item::PriceTypeQualifier::kSchoolLibrary ) {
        $priceTypeQualifier = "School Library";
    }

    my $price;
    if ( $sale->publishing_status eq BookPub::DB::Item::BookProduct::kStatusOutOfPrint ) {
        $price = "Out of Print";
    } else {
        $price = $sale->price;
    }

    $self->{'file_name'}                 = $self->_prettyFileName( $sale->file_id );
    $self->{'service'}                   = $sale->service_name;
    $self->{'format_type'}               = $sale->format;
    $self->{'date_begin'}                = Common::Client::Current()->Locale()->formatDate( $sale->date_begin );
    $self->{'date_end'}                  = Common::Client::Current()->Locale()->formatDate( $sale->date_end );
    $self->{'isbn13'}                    = $sale->isbn13;
    $self->{'isbn10'}                    = $sale->isbn10;
    $self->{'service_product_id'}        = $sale->service_product_id;
    $self->{'work_id'}                   = $sale->work_id;
    $self->{'title'}                     = $sale->book_title;
    $self->{'subtitle'}                  = $sale->book_subtitle;
    $self->{'author'}                    = BookPub::DB::Item::BookContributor->GetAuthorNamesByBookID( $sale->book_id );
    $self->{'units'}                     = Common::Client::Current()->Locale()->formatNumber( $sale->units );
    $self->{'revenue'}                   = Common::Client::Current()->Locale()->formatMoney( $sale->revenue );
    $self->{'price_type'}                = $priceType;
    $self->{'price_type_qualifier'}      = $priceTypeQualifier;
    $self->{'price_type_qualifier_code'} = $sale->price_type_qualifier_id;
    $self->{'price_effective_date'}      = $sale->start_date;
    $self->{'country_code'}              = $sale->country_code;
    $self->{'currency_code'}             = $sale->currency_code;
    $self->{'price'}                     = $price;
    $self->{'reported_currency'}         = $sale->sale_currency_code;
    $self->{'reported_price'}            = $sale->list_price;
    $self->{'variance_%'}                = Common::Client::Current()->Locale()->formatNumber( $sale->variance );
    $self->{'sales_line_num'}            = $sale->line_num;
    $self->{'status'}                    = $status;

    return $self;
}

sub _prettyFileName {
    my ( $self, $fileID ) = @_;
    my $count    = BookPub::DB::Item::File->ChildCount($fileID);
    my $file     = BookPub::DB::Item::File->Lookup( file_id => $fileID );
    my $fileName = $file->orig_file_name;

    if ( $count != 0 || $file->generation != 0 ) {
        my $displayGeneration = $file->generation + 1;
        $fileName .= " (Sp" . $displayGeneration . ")";
    }

    return $fileName;
}

1;
