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

use strict;
use warnings;
use Carp;

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


use lib '/app/tools/rps/lib';
use RPS::DB::Item::CAPublisher;
use RPS::Publisher::CA::PublisherAccount;
use Common::FormObject;
use RPS::DB::Item::FormDefaults;

use RPS::Publisher::CA::PublisherSimple;

use base 'RPS::Publisher::CA::PublisherSimple';


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

    my $timer = Common::Timer->new();
    # First, call the inherited method to get it's fields.
    #
    $self->SUPER::_propertiesFromDBItem($hrProperties, $dbItem);

    # Now we fill in the rest of the stuff.
    #
    $hrProperties->{street_address}     = $dbItem->street_address;
    $hrProperties->{street_address_2}   = $dbItem->street_address_2;
    $hrProperties->{street_address_3}   = $dbItem->street_address_3;
    $hrProperties->{city}               = $dbItem->city;
    $hrProperties->{state_province}     = $dbItem->state_province;
    $hrProperties->{country_code}       = $dbItem->country_code;
    $hrProperties->{postal_code}        = $dbItem->postal_code;
    $hrProperties->{email}              = $dbItem->email;
    $hrProperties->{phone_number}       = $dbItem->phone_number;
    $hrProperties->{fax_number}         = $dbItem->fax_number;
    $hrProperties->{tax_id}             = $dbItem->tax_id;
    $hrProperties->{statement_type_id}  = $dbItem->statement_type_id;
    $hrProperties->{affiliate_id}       = $dbItem->affiliate_id;
    $hrProperties->{cycle_code}         = $dbItem->cycle_code;
    $hrProperties->{min_payment}        = $dbItem->min_payment;
    $hrProperties->{begin_month_code}   = $dbItem->begin_month_code;
    $hrProperties->{comments}           = $dbItem->comments;
    $hrProperties->{client_account_id}  = $dbItem->client_account_id;
    $hrProperties->{status}             = $dbItem->status;
    $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) = @_;

    # Call the inherited method first, to let it get the first crack at this.
    #
    $self->SUPER::_initProperties($props);


    # Now finish the job.
    #
	$self->{StreetAddress} =    Common::FormObject::Scalar::String->new(value => $props->{street_address});
	$self->{StreetAddress2} =   Common::FormObject::Scalar::String->new(value => $props->{street_address_2});
	$self->{StreetAddress3} =   Common::FormObject::Scalar::String->new(value => $props->{street_address_3});
	$self->{City} =             Common::FormObject::Scalar::String->new(value => $props->{city}, maxlength => 80);
	$self->{StateProvince} =    Common::FormObject::Scalar::String->new(value => $props->{state_province}, maxlength => 80);
	$self->{CountryCode} =      Common::FormObject::Scalar::String->new(value => $props->{country_code});
	$self->{PostalCode} =       Common::FormObject::Scalar::String->new(value => $props->{postal_code}, maxlength => 15);
	$self->{Email} =            Common::FormObject::Scalar::EmailAddress->new(value => $props->{email}, maxlength => 80);
	$self->{PhoneNumber} =      Common::FormObject::Scalar::PhoneNumber->new(value => $props->{phone_number}, maxlength => 30);
	$self->{FaxNumber} =        Common::FormObject::Scalar::String->new(value => $props->{fax_number}, maxlength => 30);
	$self->{TaxID} =            Common::FormObject::Scalar::String->new(value => $props->{tax_id}, maxlength => 30);
	$self->{StatementTypeID} =  Common::FormObject::Scalar->new(value => $props->{statement_type_id});
	$self->{AffiliateID} =      Common::FormObject::Scalar->new(value => $props->{affiliate_id});
	$self->{CycleCode} =        Common::FormObject::Scalar->new(value => $props->{cycle_code});
	$self->{MinPayment} =       Common::FormObject::Scalar::Money->new(value => $props->{min_payment});
	$self->{BeginMonthCode} =   Common::FormObject::Scalar->new(value => $props->{begin_month_code});
	$self->{Comments} =         Common::FormObject::Scalar::String->new(value => $props->{comments}, maxlength => 0);
	$self->{ClientAccountID} =  Common::FormObject::Scalar::String->new(value => $props->{client_account_id});
	$self->{Status}             = Common::FormObject::Scalar->new(value => $props->{status});

	# we want to show the number of publishers that
	# have this publisher as an admin or as an agent
	#
	my $adminFor = 0;
	my $agentFor = 0;
	my $coll;
	$coll = RPS::DB::Item::CAPublisher->GetByAdminID($props->{publisher_id});
	$adminFor = (defined $coll) ? $coll->size : 0;

	$coll = RPS::DB::Item::CAPublisher->GetByAgentID($props->{publisher_id});
	$agentFor = (defined $coll) ? $coll->size : 0;

	$self->{AdminFor} = Common::FormObject::Scalar->new(value => $adminFor, readOnly => 1);
	$self->{AgentFor} = Common::FormObject::Scalar->new(value => $agentFor, readOnly => 1);
	$self->{UpdateAttachedPublishers} = Common::FormObject::Scalar::Boolean->new();

    $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);


	if ($self->loadSubs())
	{
        if (defined $props->{ca_publisher_id})
        {
            my $accounts = RPS::DB::Item::CAPublisherAccount->GetByPublisherID($props->{ca_publisher_id});
            while (my $account = $accounts->next())
            {
                push @{$self->{Account}}, RPS::Publisher::CA::PublisherAccount->new(_dbItem => $account, readOnly => 1);
            }
        }

	}

	return $self;
}



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

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

	if($self->StateProvince() && $self->CountryCode())
	{
		if($self->CountryCode() eq 'US')
		{
			if(! RPS::StateList::IsValidState($self->StateProvince()))
			{
				$self->{StateProvince}->setError(Common::FormObject::kErrInvalidState);
				$valid = 0;
			}
		}
	}

    return $valid;;
}


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

    my $createFlag = 0;
	my $publisherDBObj;
	if($self->PublisherID())
	{
		$publisherDBObj = RPS::DB::Item::CAPublisher->Lookup(ca_publisher_id => $self->PublisherID());
	}
	else
	{
        $createFlag = 1;
		$publisherDBObj = RPS::DB::Item::CAPublisher->Create();
	}

	my $wasAgency = $publisherDBObj->is_agency;
	my $wasAdmin  = $publisherDBObj->is_admin;

	# an agent cannot have an admin/agent set
	#
	if($self->IsAgency())
	{
		$self->AgentID(undef);
		$self->AdminID(undef);
	}
	# an admin cannot have an admin set
	#
	if($self->IsAdmin())
	{
		$self->AdminID(undef);
	}

	# set fields here
	#
	$publisherDBObj->publisher_name($self->PublisherName());
	$publisherDBObj->is_agency($self->IsAgency());
	$publisherDBObj->is_admin($self->IsAdmin());
	$publisherDBObj->street_address($self->StreetAddress());
	$publisherDBObj->street_address_2($self->StreetAddress2());
	$publisherDBObj->street_address_3($self->StreetAddress3());
	$publisherDBObj->city($self->City());
	$publisherDBObj->state_province($self->StateProvince());
	$publisherDBObj->country_code($self->CountryCode());
	$publisherDBObj->postal_code($self->PostalCode());
	$publisherDBObj->email($self->Email());
	$publisherDBObj->phone_number($self->PhoneNumber());
	$publisherDBObj->fax_number($self->FaxNumber());
	$publisherDBObj->tax_id($self->TaxID());
	$publisherDBObj->agent_id($self->AgentID());
	$publisherDBObj->admin_id($self->AdminID());
	$publisherDBObj->statement_type_id($self->StatementTypeID());
	$publisherDBObj->affiliate_id($self->AffiliateID());
	$publisherDBObj->cycle_code($self->CycleCode());
	$publisherDBObj->min_payment($self->MinPayment());
	$publisherDBObj->begin_month_code($self->BeginMonthCode());
	$publisherDBObj->comments($self->Comments());
	$publisherDBObj->client_account_id($self->ClientAccountID());
	$publisherDBObj->status($self->Status());


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


	# ----------------------------------------------------------------
	# Some clean-up code used to support "fixing" a user error where
	# they mistakenly create a publisher as an agent (or admin), then
	# attach a bunch of publishers to it, then realize this publisher
	# really should have been an admin (or agent).
	# ----------------------------------------------------------------
	#
	# if we changed from being an admin or agent then
	# we need to fix any publishers that are linked to this
	# publisher via agent_id or admin_id. we will skip ones
	# we can't resolve. UupdateAttachedPublishers is a checkbox
	# the user checks to indicate they want this "fix" to occur.
	#
	# this handles the two cases:
	# 	1. Was Agency or Admin and switched to Agency or Admin
	# 	2. Was Agency or Admin is now neither
	#
	if ($self->UpdateAttachedPublishers())
	{
		my $collection;

		# Publisher was Admin or Agent and is now neither:
		# remove this agent/admin from all attached publishers
		#
		if(!$self->IsAgency() && !$self->IsAdmin())
		{
			if($wasAgency)
			{
				# get all publishers that have this Publisher set as their Agent
				#
				$collection = RPS::DB::Item::CAPublisher->GetByAgentID($self->PublisherID());
				while($collection->hasNext())
				{
					my $dbItem = $collection->next();
					$dbItem->agent_id(undef);
					$dbItem->save();
				}
			}
			elsif($wasAdmin)
			{
				# get all publishers that have this Publisher set as their Admin
				#
				$collection = RPS::DB::Item::CAPublisher->GetByAdminID($self->PublisherID());
				while($collection->hasNext())
				{
					my $dbItem = $collection->next();
					$dbItem->admin_id(undef);
					$dbItem->save();
				}
			}
		}
		# Publisher was Agency, is now Admin:
		# switch attached publishers to use this as an admin,
		# unless they already have an admin
		#
		elsif($wasAgency && $self->IsAdmin())
		{
			# get all publishers that have this Publisher set as their Agent
			#
			$collection = RPS::DB::Item::CAPublisher->GetByAgentID($self->PublisherID());
			while($collection->hasNext())
			{
				my $dbItem = $collection->next();
				if(!$dbItem->admin_id)
				{
					$dbItem->agent_id(undef);
					$dbItem->admin_id($self->PublisherID());
					$dbItem->save();
				}
			}
		}
		# Publisher was Admin, is now Agent:
		# switch attached publishers to use this as an agent,
		# unless they already have an agent
		#
		elsif($wasAdmin && $self->IsAgency())
		{
			# get all publishers that have this Publisher set as their Admin
			#
			$collection = RPS::DB::Item::CAPublisher->GetByAdminID($self->PublisherID());
			while($collection->hasNext())
			{
				my $dbItem = $collection->next();
				if(!$dbItem->agent_id)
				{
					$dbItem->admin_id(undef);
					$dbItem->agent_id($self->PublisherID());
					$dbItem->save();
				}
			}
		}
	}


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


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

    # Take some (not necessarily all) of these fields and make them defaults.
    #
    # Note that this does _not_ imply that we are actually saving this form's data.
    # Just that we are saving it's stuff as a default.
    # (We need to apply this to the liquidation list, too, I'm thinking...)
    #
    my %newDefaults;
    $newDefaults{cycle_code} = $self->CycleCode();
    $newDefaults{min_payment} = $self->MinPayment();

    # Save these new defaults.
    #
    RPS::DB::Item::FormDefaults::ReplaceFormPropertyValues('RPS::Publisher::CA::Publisher', \%newDefaults);
}




# Accessors
#
sub Account
{
	my $self = shift @_;
	if($self->{Advance})
	{
		return $self->{Advance}{AdvanceAccount};
	}
	else
	{
		return undef;
	}
}



###
1;#
###

