<?php

namespace StructType;

use \WsdlToPhp\PackageBase\AbstractStructBase;

/**
 * This class stands for Project_Template_Request_CriteriaType StructType
 * Meta information extracted from the WSDL
 * - documentation: Contains the request criteria to identify the specific instance(s) of a project template.
 * @subpackage Structs
 */
class Project_Template_Request_CriteriaType extends AbstractStructBase
{
    /**
     * The Template_Name
     * Meta information extracted from the WSDL
     * - documentation: The name of the project template.
     * - maxOccurs: 1
     * - minOccurs: 0
     * @var string
     */
    public $Template_Name;
    /**
     * The Company_Reference
     * Meta information extracted from the WSDL
     * - documentation: The company for the project template.
     * - minOccurs: 0
     * @var \StructType\CompanyObjectType
     */
    public $Company_Reference;
    /**
     * The Project_Group_Reference
     * Meta information extracted from the WSDL
     * - documentation: The project group for the project template.
     * - minOccurs: 0
     * @var \StructType\Project_GroupObjectType
     */
    public $Project_Group_Reference;
    /**
     * The Sales_Item_Reference
     * Meta information extracted from the WSDL
     * - documentation: The sales item for the project template.
     * - minOccurs: 0
     * @var \StructType\Sales_ItemObjectType
     */
    public $Sales_Item_Reference;
    /**
     * The Billable
     * Meta information extracted from the WSDL
     * - documentation: If true, the project is billable for the project template.
     * - choice: Billable | Non-Billable | Both_Billable_and_Non-Billable
     * - choiceMaxOccurs: 1
     * - choiceMinOccurs: 1
     * - maxOccurs: 1
     * - minOccurs: 0
     * @var bool
     */
    public $Billable;
    /**
     * The Non_Billable
     * Meta information extracted from the WSDL
     * - documentation: If true, the project is non-billable for the project template.
     * - choice: Billable | Non-Billable | Both_Billable_and_Non-Billable
     * - choiceMaxOccurs: 1
     * - choiceMinOccurs: 1
     * - maxOccurs: 1
     * - minOccurs: 0
     * @var bool
     */
    public $Non_Billable;
    /**
     * The Both_Billable_and_Non_Billable
     * Meta information extracted from the WSDL
     * - documentation: If true, project templates that are both billable and non-billable are returned.
     * - choice: Billable | Non-Billable | Both_Billable_and_Non-Billable
     * - choiceMaxOccurs: 1
     * - choiceMinOccurs: 1
     * - maxOccurs: 1
     * - minOccurs: 0
     * @var bool
     */
    public $Both_Billable_and_Non_Billable;
    /**
     * Constructor method for Project_Template_Request_CriteriaType
     * @uses Project_Template_Request_CriteriaType::setTemplate_Name()
     * @uses Project_Template_Request_CriteriaType::setCompany_Reference()
     * @uses Project_Template_Request_CriteriaType::setProject_Group_Reference()
     * @uses Project_Template_Request_CriteriaType::setSales_Item_Reference()
     * @uses Project_Template_Request_CriteriaType::setBillable()
     * @uses Project_Template_Request_CriteriaType::setNon_Billable()
     * @uses Project_Template_Request_CriteriaType::setBoth_Billable_and_Non_Billable()
     * @param string $template_Name
     * @param \StructType\CompanyObjectType $company_Reference
     * @param \StructType\Project_GroupObjectType $project_Group_Reference
     * @param \StructType\Sales_ItemObjectType $sales_Item_Reference
     * @param bool $billable
     * @param bool $non_Billable
     * @param bool $both_Billable_and_Non_Billable
     */
    public function __construct($template_Name = null, \StructType\CompanyObjectType $company_Reference = null, \StructType\Project_GroupObjectType $project_Group_Reference = null, \StructType\Sales_ItemObjectType $sales_Item_Reference = null, $billable = null, $non_Billable = null, $both_Billable_and_Non_Billable = null)
    {
        $this
            ->setTemplate_Name($template_Name)
            ->setCompany_Reference($company_Reference)
            ->setProject_Group_Reference($project_Group_Reference)
            ->setSales_Item_Reference($sales_Item_Reference)
            ->setBillable($billable)
            ->setNon_Billable($non_Billable)
            ->setBoth_Billable_and_Non_Billable($both_Billable_and_Non_Billable);
    }
    /**
     * Get Template_Name value
     * @return string|null
     */
    public function getTemplate_Name()
    {
        return $this->Template_Name;
    }
    /**
     * Set Template_Name value
     * @param string $template_Name
     * @return \StructType\Project_Template_Request_CriteriaType
     */
    public function setTemplate_Name($template_Name = null)
    {
        // validation for constraint: string
        if (!is_null($template_Name) && !is_string($template_Name)) {
            throw new \InvalidArgumentException(sprintf('Invalid value %s, please provide a string, %s given', var_export($template_Name, true), gettype($template_Name)), __LINE__);
        }
        $this->Template_Name = $template_Name;
        return $this;
    }
    /**
     * Get Company_Reference value
     * @return \StructType\CompanyObjectType|null
     */
    public function getCompany_Reference()
    {
        return $this->Company_Reference;
    }
    /**
     * Set Company_Reference value
     * @param \StructType\CompanyObjectType $company_Reference
     * @return \StructType\Project_Template_Request_CriteriaType
     */
    public function setCompany_Reference(\StructType\CompanyObjectType $company_Reference = null)
    {
        $this->Company_Reference = $company_Reference;
        return $this;
    }
    /**
     * Get Project_Group_Reference value
     * @return \StructType\Project_GroupObjectType|null
     */
    public function getProject_Group_Reference()
    {
        return $this->Project_Group_Reference;
    }
    /**
     * Set Project_Group_Reference value
     * @param \StructType\Project_GroupObjectType $project_Group_Reference
     * @return \StructType\Project_Template_Request_CriteriaType
     */
    public function setProject_Group_Reference(\StructType\Project_GroupObjectType $project_Group_Reference = null)
    {
        $this->Project_Group_Reference = $project_Group_Reference;
        return $this;
    }
    /**
     * Get Sales_Item_Reference value
     * @return \StructType\Sales_ItemObjectType|null
     */
    public function getSales_Item_Reference()
    {
        return $this->Sales_Item_Reference;
    }
    /**
     * Set Sales_Item_Reference value
     * @param \StructType\Sales_ItemObjectType $sales_Item_Reference
     * @return \StructType\Project_Template_Request_CriteriaType
     */
    public function setSales_Item_Reference(\StructType\Sales_ItemObjectType $sales_Item_Reference = null)
    {
        $this->Sales_Item_Reference = $sales_Item_Reference;
        return $this;
    }
    /**
     * Get Billable value
     * @return bool|null
     */
    public function getBillable()
    {
        return isset($this->Billable) ? $this->Billable : null;
    }
    /**
     * This method is responsible for validating the value passed to the setBillable method
     * This method is willingly generated in order to preserve the one-line inline validation within the setBillable method
     * This has to validate that the property which is being set is the only one among the given choices
     * @param mixed $value
     * @return string A non-empty message if the values does not match the validation rules
     */
    public function validateBillableForChoiceConstraintsFromSetBillable($value)
    {
        $message = '';
        if (is_null($value)) {
            return $message;
        }
        $properties = [
            'Non_Billable',
            'Both_Billable_and_Non_Billable',
        ];
        try {
            foreach ($properties as $property) {
                if (isset($this->{$property})) {
                    throw new \InvalidArgumentException(sprintf('The property Billable can\'t be set as the property %s is already set. Only one property must be set among these properties: Billable, %s.', $property, implode(', ', $properties)), __LINE__);
                }
            }
        } catch (\InvalidArgumentException $e) {
            $message = $e->getMessage();
        }
        return $message;
    }
    /**
     * Set Billable value
     * This property belongs to a choice that allows only one property to exist. It is
     * therefore removable from the request, consequently if the value assigned to this
     * property is null, the property is removed from this object
     * @throws \InvalidArgumentException
     * @param bool $billable
     * @return \StructType\Project_Template_Request_CriteriaType
     */
    public function setBillable($billable = null)
    {
        // validation for constraint: boolean
        if (!is_null($billable) && !is_bool($billable)) {
            throw new \InvalidArgumentException(sprintf('Invalid value %s, please provide a bool, %s given', var_export($billable, true), gettype($billable)), __LINE__);
        }
        // validation for constraint: choice(Billable, Non-Billable, Both_Billable_and_Non-Billable)
        if ('' !== ($billableChoiceErrorMessage = self::validateBillableForChoiceConstraintsFromSetBillable($billable))) {
            throw new \InvalidArgumentException($billableChoiceErrorMessage, __LINE__);
        }
        if (is_null($billable) || (is_array($billable) && empty($billable))) {
            unset($this->Billable);
        } else {
            $this->Billable = $billable;
        }
        return $this;
    }
    /**
     * Get Non_Billable value
     * @return bool|null
     */
    public function getNon_Billable()
    {
        return isset($this->{'Non-Billable'}) ? $this->{'Non-Billable'} : null;
    }
    /**
     * This method is responsible for validating the value passed to the setNon_Billable method
     * This method is willingly generated in order to preserve the one-line inline validation within the setNon_Billable method
     * This has to validate that the property which is being set is the only one among the given choices
     * @param mixed $value
     * @return string A non-empty message if the values does not match the validation rules
     */
    public function validateNon_BillableForChoiceConstraintsFromSetNon_Billable($value)
    {
        $message = '';
        if (is_null($value)) {
            return $message;
        }
        $properties = [
            'Billable',
            'Both_Billable_and_Non_Billable',
        ];
        try {
            foreach ($properties as $property) {
                if (isset($this->{$property})) {
                    throw new \InvalidArgumentException(sprintf('The property Non-Billable can\'t be set as the property %s is already set. Only one property must be set among these properties: Non-Billable, %s.', $property, implode(', ', $properties)), __LINE__);
                }
            }
        } catch (\InvalidArgumentException $e) {
            $message = $e->getMessage();
        }
        return $message;
    }
    /**
     * Set Non_Billable value
     * This property belongs to a choice that allows only one property to exist. It is
     * therefore removable from the request, consequently if the value assigned to this
     * property is null, the property is removed from this object
     * @throws \InvalidArgumentException
     * @param bool $non_Billable
     * @return \StructType\Project_Template_Request_CriteriaType
     */
    public function setNon_Billable($non_Billable = null)
    {
        // validation for constraint: boolean
        if (!is_null($non_Billable) && !is_bool($non_Billable)) {
            throw new \InvalidArgumentException(sprintf('Invalid value %s, please provide a bool, %s given', var_export($non_Billable, true), gettype($non_Billable)), __LINE__);
        }
        // validation for constraint: choice(Billable, Non-Billable, Both_Billable_and_Non-Billable)
        if ('' !== ($non_BillableChoiceErrorMessage = self::validateNon_BillableForChoiceConstraintsFromSetNon_Billable($non_Billable))) {
            throw new \InvalidArgumentException($non_BillableChoiceErrorMessage, __LINE__);
        }
        if (is_null($non_Billable) || (is_array($non_Billable) && empty($non_Billable))) {
            unset($this->Non_Billable, $this->{'Non-Billable'});
        } else {
            $this->Non_Billable = $this->{'Non-Billable'} = $non_Billable;
        }
        return $this;
    }
    /**
     * Get Both_Billable_and_Non_Billable value
     * @return bool|null
     */
    public function getBoth_Billable_and_Non_Billable()
    {
        return isset($this->{'Both_Billable_and_Non-Billable'}) ? $this->{'Both_Billable_and_Non-Billable'} : null;
    }
    /**
     * This method is responsible for validating the value passed to the setBoth_Billable_and_Non_Billable method
     * This method is willingly generated in order to preserve the one-line inline validation within the setBoth_Billable_and_Non_Billable method
     * This has to validate that the property which is being set is the only one among the given choices
     * @param mixed $value
     * @return string A non-empty message if the values does not match the validation rules
     */
    public function validateBoth_Billable_and_Non_BillableForChoiceConstraintsFromSetBoth_Billable_and_Non_Billable($value)
    {
        $message = '';
        if (is_null($value)) {
            return $message;
        }
        $properties = [
            'Billable',
            'Non_Billable',
        ];
        try {
            foreach ($properties as $property) {
                if (isset($this->{$property})) {
                    throw new \InvalidArgumentException(sprintf('The property Both_Billable_and_Non-Billable can\'t be set as the property %s is already set. Only one property must be set among these properties: Both_Billable_and_Non-Billable, %s.', $property, implode(', ', $properties)), __LINE__);
                }
            }
        } catch (\InvalidArgumentException $e) {
            $message = $e->getMessage();
        }
        return $message;
    }
    /**
     * Set Both_Billable_and_Non_Billable value
     * This property belongs to a choice that allows only one property to exist. It is
     * therefore removable from the request, consequently if the value assigned to this
     * property is null, the property is removed from this object
     * @throws \InvalidArgumentException
     * @param bool $both_Billable_and_Non_Billable
     * @return \StructType\Project_Template_Request_CriteriaType
     */
    public function setBoth_Billable_and_Non_Billable($both_Billable_and_Non_Billable = null)
    {
        // validation for constraint: boolean
        if (!is_null($both_Billable_and_Non_Billable) && !is_bool($both_Billable_and_Non_Billable)) {
            throw new \InvalidArgumentException(sprintf('Invalid value %s, please provide a bool, %s given', var_export($both_Billable_and_Non_Billable, true), gettype($both_Billable_and_Non_Billable)), __LINE__);
        }
        // validation for constraint: choice(Billable, Non-Billable, Both_Billable_and_Non-Billable)
        if ('' !== ($both_Billable_and_Non_BillableChoiceErrorMessage = self::validateBoth_Billable_and_Non_BillableForChoiceConstraintsFromSetBoth_Billable_and_Non_Billable($both_Billable_and_Non_Billable))) {
            throw new \InvalidArgumentException($both_Billable_and_Non_BillableChoiceErrorMessage, __LINE__);
        }
        if (is_null($both_Billable_and_Non_Billable) || (is_array($both_Billable_and_Non_Billable) && empty($both_Billable_and_Non_Billable))) {
            unset($this->Both_Billable_and_Non_Billable, $this->{'Both_Billable_and_Non-Billable'});
        } else {
            $this->Both_Billable_and_Non_Billable = $this->{'Both_Billable_and_Non-Billable'} = $both_Billable_and_Non_Billable;
        }
        return $this;
    }
}
