#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package RPS::ArtistContract::Term;

use strict;
use warnings;
use Carp;
use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::Assert;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::NewArtistContract;
use RPS::DB::Item::NewArtistContractTerm;
use RPS::DB::Item::ContractTermSource;
use RPS::ArtistContract::ProductFormat;
use RPS::ArtistContract::ChannelList;
use RPS::Region::RegionList;
use RPS::DB::Item::ContractRateType;

use Common::FormObject;
use base 'Common::FormObject';


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

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

    my %properties;

    if($args{_dbItem})
    {
        $self->_propertiesFromDBItem(\%properties, $args{_dbItem});
    }
    elsif($args{artistContractTermID})
    {
        $self->_propertiesFromDB(\%properties, $args{artistContractTermID});
    }
    else
    {
        $self->_propertiesFromDefaults(\%properties, $args{artistContractID});
    }

    $self->_initProperties(\%properties);
    $self->_initSubs(\%properties);

    return $self;
}


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

    my $dbItem = RPS::DB::Item::NewArtistContractTerm->Lookup(artist_contract_term_id => $id);
    $self->_propertiesFromDBItem($hrProperties, $dbItem);
}


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

	$self->{_inDB} = 1;

    $hrProperties->{artist_contract_term_id} = $dbItem->artist_contract_term_id;
    $hrProperties->{artist_contract_id} = $dbItem->artist_contract_id;
    $hrProperties->{priority} = $dbItem->priority;
    $hrProperties->{contract_term_source_id} = $dbItem->contract_term_source_id;
    $hrProperties->{region_id} = $dbItem->region_id;
    $hrProperties->{channel_id} = $dbItem->channel_id;
    $hrProperties->{price_level_id} = $dbItem->price_level_id;
    $hrProperties->{contract_rate_type_id} = $dbItem->contract_rate_type_id;
    $hrProperties->{rate} = $dbItem->rate;
    $hrProperties->{rate_reduction} = $dbItem->rate_reduction;
    $hrProperties->{percentage_of_sales} = $dbItem->percentage_of_sales;
    $hrProperties->{packaging_deduction} = $dbItem->packaging_deduction;
    $hrProperties->{free_goods_deduction} = $dbItem->free_goods_deduction;

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


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

    $self->{ArtistContractTermID}	= Common::FormObject::Scalar->new(value => $props->{artist_contract_term_id}, readOnly => 1);
    $self->{ArtistContractID}		= Common::FormObject::Scalar->new(value => $props->{artist_contract_id});
    $self->{Priority}		    	= Common::FormObject::Scalar->new(value => $props->{priority}, required => 1);
    $self->{ContractTermSourceID}	= Common::FormObject::Scalar->new(value => $props->{contract_term_source_id}, required => 1);
    $self->{RegionID}				= Common::FormObject::Scalar->new(value => $props->{region_id}, required => 1);
    $self->{ChannelID}				= Common::FormObject::Scalar->new(value => $props->{channel_id});
    $self->{PriceLevelID}			= Common::FormObject::Scalar->new(value => $props->{price_level_id});
    $self->{ContractRateTypeID}		= Common::FormObject::Scalar->new(value => $props->{contract_rate_type_id}, required => 1);

    $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);
    $self->{CreatedBy}          = Common::FormObject::Scalar::UserName->new(value => $props->{ created_by}, readOnly => 1);
    $self->{ModifiedBy}         = Common::FormObject::Scalar::UserName->new(value => $props->{ modified_by}, readOnly => 1);


    # We're going to force some values if the non-payable rate type has been selected.
    
    my ($rate, $rateReduction, $percentageOfSales, $packagingDeduction, $freeGoods);
    
    if ($props->{contract_rate_type_id} == RPS::DB::Item::ContractRateType::kRateTypeNonPayable())
    {
        $rate               = 0;
        $rateReduction      = 100;
        $percentageOfSales  = 100;
        $packagingDeduction = 0;
        $freeGoods          = 0;
    }
    else
    {
        $rate               = $props->{rate};
        $rateReduction      = $props->{rate_reduction};
        $percentageOfSales  = $props->{percentage_of_sales};
        $packagingDeduction = $props->{packaging_deduction};
        $freeGoods          = $props->{free_goods_deduction};        
    }
    
    $self->{Rate}			    = Common::FormObject::Scalar::Decimal->new(value => $rate, precision => '.4');
    $self->{RateReduction}			= Common::FormObject::Scalar::Percent->new(value => $rateReduction, maxValue => 300);
    $self->{PercentageOfSales}		= Common::FormObject::Scalar::Percent->new(value => $percentageOfSales);
    $self->{PackagingDeduction}		= Common::FormObject::Scalar::Percent->new(value => $packagingDeduction);
    $self->{FreeGoodsDeduction}		= Common::FormObject::Scalar::Percent->new(value => $freeGoods);

	# this is how the template tells the backend to delete one of these.
	# the default is 'OFF' (ie. don't delete)
	#
	$self->{Delete} = Common::FormObject::Scalar::Boolean->new();
}


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


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

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


    if ($self->Delete())
    {
        if ($self->hasDependency())
        {
            $self->{Delete}->setError('has_dependency');
            return 0;
        }
        # else, no need to validate any properties
        return 1;
    }

	foreach my $field (qw(ContractTermSourceID RegionID ChannelID PriceLevelID ContractRateTypeID Rate RateReduction PercentageOfSales PackagingDeduction FreeGoodsDeduction))
	{
		if($self->$field())
		{
			$self->{_hasData} = 1;
		}
	}
	
	if($self->{_hasData})
	{
		my $valid = $self->SUPER::validate();
		
		# contract term source is always required
		if(!defined $self->ContractTermSourceID())
		{
			$self->{ContractTermSourceID}->setError(Common::FormObject::kErrFieldBlank);
  	        $valid = 0;
		}		
		else 
		{
		    # Rate is required unless the non-payable rate type has been selected.
		    #
			if ($self->ContractRateTypeID() != RPS::DB::Item::ContractRateType::kRateTypeNonPayable())	
		    {
				if(!defined $self->Rate())
				{
					$self->{Rate}->setError(Common::FormObject::kErrFieldBlank);
	    			$valid = 0;
				}		        
		    }
				
			# only physical products need a channel and price level
			#
			if($self->_isPhysical())
			{
				if(!defined $self->ChannelID())
				{
					$self->{ChannelID}->setError(Common::FormObject::kErrFieldBlank);
	    			$valid = 0;
				}
				if(!defined $self->PriceLevelID())
				{
					$self->{PriceLevelID}->setError(Common::FormObject::kErrFieldBlank);
	    			$valid = 0;
				}
			}

			# terms with the following digital sources must have a rate type of % net revenue
			#
#			if($self->IncomeSourceID() == RPS::DB::Item::IncomeSource::kIncomeSourceVPD() ||
#	           $self->IncomeSourceID() == RPS::DB::Item::IncomeSource::kIncomeSourceDigitalStream() ||
#	           $self->IncomeSourceID() == RPS::DB::Item::IncomeSource::kIncomeSourceDigitalTethered())
#	           #$self->IncomeSourceID() == RPS::DB::Item::IncomeSource::kIncomeSourceDigitalAlbumPremium() ||
#	           #$self->IncomeSourceID() == RPS::DB::Item::IncomeSource::kIncomeSourceDigitalTrackPremium() ||
#	           #$self->IncomeSourceID() == RPS::DB::Item::IncomeSource::kIncomeSourceDigitalAlbumUpgrade() ||
#	           #$self->IncomeSourceID() == RPS::DB::Item::IncomeSource::kIncomeSourceDigitalTrackUpgrade())
#			{
#				if(($self->ContractRateTypeID() != RPS::DB::Item::ContractRateType::kRateTypePercentRevenue()) && 
#				   ($self->ContractRateTypeID() != RPS::DB::Item::ContractRateType::kRateTypeNonPayable()))
#				{
#					$self->{ContractRateTypeID}->setError(Common::FormObject::kErrFieldInvalid);
#	    			$valid = 0;
#				}
#			}
					
		}
		
    return $valid;
	}
	else
	{
		return 1;
	}
}

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

    my $hasDigital = RPS::DB::Item::ContractTermSource->hasDigital( $self->ContractTermSourceID() );
    return $hasDigital ? undef : 1;
}

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

	if ($self->Delete())
	{
		$self->delete();
		return;
	}

    return unless $self->{_hasData};


	my $dbObj;
	if($self->ArtistContractTermID())
	{
		$dbObj = RPS::DB::Item::NewArtistContractTerm->Lookup(artist_contract_term_id => $self->ArtistContractTermID());
	}
	else
	{
		$dbObj = RPS::DB::Item::NewArtistContractTerm->Create();
	}

	# set fields here
	#
	$dbObj->artist_contract_id($self->ArtistContractID());
    $dbObj->priority($self->Priority());
    $dbObj->contract_term_source_id($self->ContractTermSourceID());
    $dbObj->region_id($self->RegionID());
    $dbObj->channel_id($self->ChannelID());
    $dbObj->price_level_id($self->PriceLevelID());
    $dbObj->contract_rate_type_id($self->ContractRateTypeID());
    $dbObj->rate($self->Rate());
    $dbObj->modified_by($self->ModifiedBy());
    $dbObj->date_modified(Common::DB::Item::kDateTimeNow);


    # rate_reduction and percentage_of_sales need to default to 100, not 0.
    #
    $dbObj->rate_reduction( $self->RateReduction() > 0 ? $self->RateReduction() : 100);
    $dbObj->percentage_of_sales( $self->PercentageOfSales() > 0 ? $self->PercentageOfSales() : 100);

    $dbObj->packaging_deduction($self->PackagingDeduction());
    $dbObj->free_goods_deduction($self->FreeGoodsDeduction());

	# a little massaging of the data,
	# if we change a physical term to a digital then we need
	# to blank out certain fields that don't apply to digital
	#
	if(!$self->_isPhysical())
	{
		$dbObj->channel_id(undef);
		$dbObj->price_level_id(undef);
	}

	# save db item
	#
	$dbObj->save();

	# reload object
	#
	$self->_init(_dbItem => $dbObj);
}

sub setDependency
{
	my $self = shift;
    $self->{HasDependency} = 1;
}

sub hasDependency
{
	my $self = shift;
    return $self->{HasDependency} ? 1 : 0;
}

sub delete
{
	my $self = shift;

	if($self->{_inDB})
	{
		my $myDBObj = RPS::DB::Item::NewArtistContractTerm->Lookup(artist_contract_term_id => $self->ArtistContractTermID());
		$myDBObj->delete();
	}
    return 1;
}


###
1;#
###
