#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package RPS::License::BaseTrackLicense;

use strict;
use warnings;
use Data::Dumper;
use Carp;
use Date::Calc qw( Date_to_Days Decode_Date_US );

use lib '/app/tools/common/lib';
use Common::Assert;
use Common::Util qw(decodeDateMysql);
use Common::Log;

use lib '/app/tools/rps/lib';
use RPS::License::BaseLicense;
use RPS::License::RateBasis;
use RPS::License::RateType;
use RPS::DB::Item::RegionCountryMap;
use RPS::DB::Item::Product;
use RPS::DB::Item::ReserveLiquidation;
use RPS::DB::Item::ProductType;
use RPS::Finance::Account;

use Common::FormObject;
use base 'RPS::License::BaseLicense';


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

    $self->SUPER::_propertiesFromDefaults($hrProperties, %args);
    $hrProperties->{type} = $self->_type();
}


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

	$self->SUPER::_initProperties($props);

    $self->{ProductTypeID}      = Common::FormObject::Scalar->new(value => $props->{product_type_id});
    $self->{FinanceAccountID}   = Common::FormObject::Scalar->new(value => $props->{finance_account_id});

    $self->{RateType}           = Common::FormObject::Scalar->new(value => $props->{rate_type}, required => 1);
    $self->{RateBasis}          = Common::FormObject::Scalar->new(value => $props->{rate_basis});
    $self->{PennyRate}          = Common::FormObject::Scalar::Decimal->new(value => $props->{penny_rate}, precision => '.4', minValue => '0.0001');
    $self->{ReservePercentage}  = Common::FormObject::Scalar::Percent->new(value => $props->{reserve_percentage});

    # jpk - this is a bit of a hack - We have some rate_percentage values that are set to 0 or NULL, which is wrong.
    # Those should be set to 100%.
    my $ratePercentage = $props->{rate_percentage};
    $ratePercentage = 100 unless (defined $ratePercentage && $ratePercentage > 0);
    $self->{RatePercentage}     = Common::FormObject::Scalar::Percent->new(value => $ratePercentage, maxValue => 9999);

    $self->{PercentageOfSales}  = Common::FormObject::Scalar::Percent->new(value => $props->{percentage_of_sales},
                                                                       required => 1, minValue => 1);
    $self->{FreeGoods}          = Common::FormObject::Scalar::Percent->new(value => $props->{free_goods});
    $self->{MiscDeduction}      = Common::FormObject::Scalar::Percent->new(value => $props->{misc_deduction});

    $self->{CrossCollateralized}	= Common::FormObject::Scalar::Boolean->new(value => $props->{cross_collateralized});


}


sub validate
{
	my ($self, $skipRequiredFields) = @_;

	my $valid = $self->SUPER::validate($skipRequiredFields);

    return $valid if $skipRequiredFields;


    # 'rest of world' is not a valid region for a TrackLicense
    #
    if (0 == $self->RegionID())
    {
        Common::Log::Print("TrackLicense::validate - 0 is not a valid region id");
        $self->{RegionID}->setError(Common::FormObject::kErrFieldBlank);
        $valid = 0;
    }


    # If the product type is 'all' or 'digital album', the region must not contain any countries
    # other than US or Canada.
    # !!! This constraint may be just for US licences... But for now I will leave this here.
    #
    if (! $self->ProductTypeID() ||
    RPS::DB::Item::Product::kProductTypeDigital == $self->ProductTypeID() || RPS::DB::Item::Product::kProductTypeDigitalTrack == $self->ProductTypeID() || RPS::DB::Item::Product::kProductTypeRingtone == $self->ProductTypeID())
    {
        my $mapItems = RPS::DB::Item::RegionCountryMap->GetByRegionID($self->RegionID());
        while (my $mapItem = $mapItems->next())
        {
            # !!! We ought to have these defined as constants someplace...
            # !!! The stuff in Const.pm is crap.
            #
            if ('US' ne $mapItem->country_code && 'CA' ne $mapItem->country_code)
            {
                Common::Log::Print("TrackLicense::validate - attempting to use a region with a non us or ca country code on an all products or digital license");
                $self->{RegionID}->setError(Common::FormObject::kErrFieldInvalid);
                $valid = 0;
                last;
            }
        }
    }


    # In any event, we can't use a region that contains a country that is already here.
    #
    # So, first, get all the region ids from licenses that have the same publisher,track, and product type.
    # !!! This will have to be overridden to account for TrackLicense types correctly.
    #
    my $countryCodeMap = $self->_getCountryCodeMapForValidation();

    # Make sure _our_ region doesn't have any of these countries in it.
    #
    my $ccMapItems = RPS::DB::Item::RegionCountryMap->GetByRegionID($self->RegionID());
    while (my $mapItem = $ccMapItems->next())
    {
        if ($countryCodeMap->{$mapItem->country_code})
        {
            print STDERR "TrackLicense::validate - this track, publisher, and product type is already licensed on country code " . $mapItem->country_code . "\n";
            $self->{RegionID}->setError(Common::FormObject::kErrFieldInvalid);
            $valid = 0;
            last;
        }
    }


    # Not going to allow penny rates of '0', or '0.000', or that sort of thing.
    #
    if (RPS::License::RateType::kPenny == $self->RateType())
    {
        if (! $self->PennyRate())
        {
		    $self->{PennyRate}->setError(Common::FormObject::kErrFieldBlank);
		    $valid = 0;
        }
        elsif ($self->PennyRate() < 0.0001)
        {
		    $self->{PennyRate}->setError(Common::FormObject::kErrFieldOutOfRange);
		    $valid = 0;
        }
    }

	# RateBasis is only required if the rate type is not penny rate
	#
	if(! $self->RateBasis() && $self->RateType() != RPS::License::RateType::kPenny)
	{
		$self->{RateBasis}->setError(Common::FormObject::kErrFieldBlank);
		$valid = 0;
	}

    if (RPS::License::RateBasis::kLock == $self->RateBasis() && !$self->LockDate())
    {
		$self->{LockDate}->setError(Common::FormObject::kErrFieldBlank);
		$valid = 0;
    }


	return $valid;
}


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

	$self->SUPER::_setDBValues($dbItem);

	$dbItem->product_type_id($self->ProductTypeID());
	$dbItem->rate_basis($self->RateBasis());
	$dbItem->rate_type($self->RateType());
	$dbItem->penny_rate($self->PennyRate());
	$dbItem->finance_account_id($self->FinanceAccountID());
	$dbItem->reserve_percentage($self->ReservePercentage());
	$dbItem->rate_percentage($self->RatePercentage());
	$dbItem->percentage_of_sales($self->PercentageOfSales());
	$dbItem->free_goods($self->FreeGoods());
	$dbItem->misc_deduction($self->MiscDeduction());
    $dbItem->cross_collateralized($self->CrossCollateralized());

    $dbItem->comments($self->Comments());
}

sub _getMatchingProductTypes {
	my $self = shift;
	my $productTypeID = shift || return;

	my $collection;

	if( $productTypeID == RPS::DB::Item::ProductType::kAllPhysicalProducts ) {
		$collection = RPS::DB::Item::ProductType->GetAllPhysical();
	}
	elsif( $productTypeID == RPS::DB::Item::ProductType::kAllDigitalProducts ) {
		$collection = RPS::DB::Item::ProductType->GetAllDigital();
	}
	else {
		return [ $productTypeID ];
	}

    my @result;

	while ( my $row = $collection->next() ) {
		push( @result, $row->product_type_id );
	}

	return @result ? \@result : undef;
}

###
1;#
###
