package BookPub::Import::SaleRec;
#
# By putting SaleRec into its own package, we can override accessor methods to do fancy stuff.
#
use strict;

use Class::Struct;
use Data::Dumper;

use lib '/app/tools/common/lib';
use lib '/app/tools/bookpub/lib';
use Common::Log;
use BookPub::DB::Item::Sale;

struct 'BookPub::Import::SaleRec' => {
    serviceID            => '$',
    importStatus         => '$',
    productType          => '$',
    formatType           => '$',
    purchaseType         => '$',
    serviceProductID     => '$',
    priceTypeID          => '$',
    priceTypeQualifierID => '$',
    isAgency             => '$',
    isFree               => '$',
    isPreOrder           => '$',
    units                => '$',
    listPrice            => '$',
    discount             => '$',
    unitPrice            => '$',
    revenue              => '$',
    taxAmount            => '$',
    conversionRate       => '$',
    currencyCode         => '$',
    countryCode          => '$',
    state                => '$',
    postalCode           => '$',
    incentiveAmount      => '$',
    lineNum              => '$',
    dateBegin            => '$',
    dateEnd              => '$',

    # the following are "r_" fields
    rFormat                  => '$',
    rPriceType               => '$',
    rPurchaseType            => '$',
    rServiceName             => '$',
    rDistributor             => '$',
    rProductType             => '$',
    rClientProductID         => '$',
    rIsbn10                  => '$',
    rIsbn13                  => '$',
    rTitle                   => '$',
    rSubtitle                => '$',
    rAuthor                  => '$',
    rChapterTitle            => '$',
    rChapterOrdinal          => '$',
    rImprint                 => '$',
    rNarrator                => '$',
    rComments                => '$',
    rChannel                 => '$',
    rUnits                   => '$',
    rSales                   => '$',
    rReturns                 => '$',
    rAdjustments             => '$',
    rFee                     => '$',
    rTaxUnitPrice            => '$',
    rTaxAmount               => '$',
    rPurchasePrice           => '$',
    rPurchasePriceCurrency   => '$',
    rListPrice               => '$',
    rListPriceCurrency       => '$',
    rNativeListPrice         => '$',
    rNativeListPriceCurrency => '$',
    rDiscount                => '$',
    rCOGS                    => '$',
    rUnitPrice               => '$',
    rRevenue                 => '$',
    rPromoCode               => '$',
    rState                   => '$',
    rPostalCode              => '$',
    rDuration                => '$',
    rPreviousDuration        => '$',
    rInstitution             => '$',
    rIncentiveAmount         => '$',
    rModel                   => '$',
    rDeliveryMethod          => '$',
    rTransactionCategory     => '$',
};

sub _floatAccessor {
    my ( $self, $field, $inArg ) = @_;

    if ( defined $inArg ) {

        # Convert negative scientific notation back to an expanded string notation.
        # If the value seems like gibberish, go ahead and store it...
        # We'll validate later.
        #
        if ( $inArg =~ /\d+\.\d+e-\d+/ ) {

            # sprintf is pure magic.
            #
            $inArg = sprintf( "%.8f", $inArg );
        }
        $self->{$field} = $inArg;
    }

    return $self->{$field};
}

sub totalRevenue {
    my ( $self, $inArg ) = @_;

    return $self->_floatAccessor( 'totalRevenue', $inArg );
}

sub _tryToIntAccessor {
    my ( $self, $field, $inArg ) = @_;

    $inArg =~ s/[^\de.+-]/ /ig;
    ($inArg) = split ' ', $inArg;
    if ( $inArg =~ /^[+-]?(?:\d|\.\d)\d*(\.\d*)?(E[+-]?\d+)?$/i ) {
        $inArg = $field eq 'rIsbn10'
            ? sprintf('%010d', $inArg)
            : sprintf('%013d', $inArg);
    }

    return $self->{$field} = abs($inArg);
}

sub rIsbn10 {
    my ( $self, $inArg ) = @_;

    return $self->{rIsbn10} unless defined $inArg;
    return $self->_tryToIntAccessor( 'rIsbn10', $inArg );
}

sub rIsbn13 {
    my ( $self, $inArg, $productType ) = @_;

    return $self->{rIsbn13} unless defined $inArg;

    # We don't want to convert isbn13 to int if E-Journal product is found. ISSN is being populated in ISBN13 field.
    return $self->{rIsbn13} = $inArg if ($productType eq BookPub::DB::Item::Sale::kProductTypeEJournal);

    return $self->_tryToIntAccessor( 'rIsbn13', $inArg );
}

1;
