<?php



namespace PayPal\Api;



use PayPal\Common\PayPalModel;

use PayPal\Common\PayPalResourceModel;

use PayPal\Rest\ApiContext;

use PayPal\Transport\PayPalRestCall;

use PayPal\Validation\ArgumentValidator;



/**

 * Class Plan

 *

 * Billing plan resource that will be used to create a billing agreement.

 *

 * @package PayPal\Api

 *

 * @property string id

 * @property string name

 * @property string description

 * @property string type

 * @property string state

 * @property string create_time

 * @property string update_time

 * @property \PayPal\Api\PaymentDefinition[] payment_definitions

 * @property \PayPal\Api\Terms[] terms

 * @property \PayPal\Api\MerchantPreferences merchant_preferences

 */

class Plan extends PayPalResourceModel

{

    /**

     * Identifier of the billing plan. 128 characters max.

     *

     * @param string $id

     * 

     * @return $this

     */

    public function setId($id)

    {

        $this->id = $id;

        return $this;

    }



    /**

     * Identifier of the billing plan. 128 characters max.

     *

     * @return string

     */

    public function getId()

    {

        return $this->id;

    }



    /**

     * Name of the billing plan. 128 characters max.

     *

     * @param string $name

     * 

     * @return $this

     */

    public function setName($name)

    {

        $this->name = $name;

        return $this;

    }



    /**

     * Name of the billing plan. 128 characters max.

     *

     * @return string

     */

    public function getName()

    {

        return $this->name;

    }



    /**

     * Description of the billing plan. 128 characters max.

     *

     * @param string $description

     * 

     * @return $this

     */

    public function setDescription($description)

    {

        $this->description = $description;

        return $this;

    }



    /**

     * Description of the billing plan. 128 characters max.

     *

     * @return string

     */

    public function getDescription()

    {

        return $this->description;

    }



    /**

     * Type of the billing plan. Allowed values: `FIXED`, `INFINITE`.

     *

     * @param string $type

     * 

     * @return $this

     */

    public function setType($type)

    {

        $this->type = $type;

        return $this;

    }



    /**

     * Type of the billing plan. Allowed values: `FIXED`, `INFINITE`.

     *

     * @return string

     */

    public function getType()

    {

        return $this->type;

    }



    /**

     * Status of the billing plan. Allowed values: `CREATED`, `ACTIVE`, `INACTIVE`, and `DELETED`.

     *

     * @param string $state

     * 

     * @return $this

     */

    public function setState($state)

    {

        $this->state = $state;

        return $this;

    }



    /**

     * Status of the billing plan. Allowed values: `CREATED`, `ACTIVE`, `INACTIVE`, and `DELETED`.

     *

     * @return string

     */

    public function getState()

    {

        return $this->state;

    }



    /**

     * Time when the billing plan was created. Format YYYY-MM-DDTimeTimezone, as defined in [ISO8601](http://tools.ietf.org/html/rfc3339#section-5.6).

     *

     * @param string $create_time

     * 

     * @return $this

     */

    public function setCreateTime($create_time)

    {

        $this->create_time = $create_time;

        return $this;

    }



    /**

     * Time when the billing plan was created. Format YYYY-MM-DDTimeTimezone, as defined in [ISO8601](http://tools.ietf.org/html/rfc3339#section-5.6).

     *

     * @return string

     */

    public function getCreateTime()

    {

        return $this->create_time;

    }



    /**

     * Time when this billing plan was updated. Format YYYY-MM-DDTimeTimezone, as defined in [ISO8601](http://tools.ietf.org/html/rfc3339#section-5.6).

     *

     * @param string $update_time

     * 

     * @return $this

     */

    public function setUpdateTime($update_time)

    {

        $this->update_time = $update_time;

        return $this;

    }



    /**

     * Time when this billing plan was updated. Format YYYY-MM-DDTimeTimezone, as defined in [ISO8601](http://tools.ietf.org/html/rfc3339#section-5.6).

     *

     * @return string

     */

    public function getUpdateTime()

    {

        return $this->update_time;

    }



    /**

     * Array of payment definitions for this billing plan.

     *

     * @param \PayPal\Api\PaymentDefinition[] $payment_definitions

     * 

     * @return $this

     */

    public function setPaymentDefinitions($payment_definitions)

    {

        $this->payment_definitions = $payment_definitions;

        return $this;

    }



    /**

     * Array of payment definitions for this billing plan.

     *

     * @return \PayPal\Api\PaymentDefinition[]

     */

    public function getPaymentDefinitions()

    {

        return $this->payment_definitions;

    }



    /**

     * Append PaymentDefinitions to the list.

     *

     * @param \PayPal\Api\PaymentDefinition $paymentDefinition

     * @return $this

     */

    public function addPaymentDefinition($paymentDefinition)

    {

        if (!$this->getPaymentDefinitions()) {

            return $this->setPaymentDefinitions(array($paymentDefinition));

        } else {

            return $this->setPaymentDefinitions(

                array_merge($this->getPaymentDefinitions(), array($paymentDefinition))

            );

        }

    }



    /**

     * Remove PaymentDefinitions from the list.

     *

     * @param \PayPal\Api\PaymentDefinition $paymentDefinition

     * @return $this

     */

    public function removePaymentDefinition($paymentDefinition)

    {

        return $this->setPaymentDefinitions(

            array_diff($this->getPaymentDefinitions(), array($paymentDefinition))

        );

    }



    /**

     * Array of terms for this billing plan.

     *

     * @param \PayPal\Api\Terms[] $terms

     * 

     * @return $this

     */

    public function setTerms($terms)

    {

        $this->terms = $terms;

        return $this;

    }



    /**

     * Array of terms for this billing plan.

     *

     * @return \PayPal\Api\Terms[]

     */

    public function getTerms()

    {

        return $this->terms;

    }



    /**

     * Append Terms to the list.

     *

     * @param \PayPal\Api\Terms $terms

     * @return $this

     */

    public function addTerm($terms)

    {

        if (!$this->getTerms()) {

            return $this->setTerms(array($terms));

        } else {

            return $this->setTerms(

                array_merge($this->getTerms(), array($terms))

            );

        }

    }



    /**

     * Remove Terms from the list.

     *

     * @param \PayPal\Api\Terms $terms

     * @return $this

     */

    public function removeTerm($terms)

    {

        return $this->setTerms(

            array_diff($this->getTerms(), array($terms))

        );

    }



    /**

     * Specific preferences such as: set up fee, max fail attempts, autobill amount, and others that are configured for this billing plan.

     *

     * @param \PayPal\Api\MerchantPreferences $merchant_preferences

     * 

     * @return $this

     */

    public function setMerchantPreferences($merchant_preferences)

    {

        $this->merchant_preferences = $merchant_preferences;

        return $this;

    }



    /**

     * Specific preferences such as: set up fee, max fail attempts, autobill amount, and others that are configured for this billing plan.

     *

     * @return \PayPal\Api\MerchantPreferences

     */

    public function getMerchantPreferences()

    {

        return $this->merchant_preferences;

    }



    /**

     * Retrieve the details for a particular billing plan by passing the billing plan ID to the request URI.

     *

     * @param string $planId

     * @param ApiContext $apiContext is the APIContext for this call. It can be used to pass dynamic configuration and credentials.

     * @param PayPalRestCall $restCall is the Rest Call Service that is used to make rest calls

     * @return Plan

     */

    public static function get($planId, $apiContext = null, $restCall = null)

    {

        ArgumentValidator::validate($planId, 'planId');

        $payLoad = "";

        $json = self::executeCall(

            "/v1/payments/billing-plans/$planId",

            "GET",

            $payLoad,

            null,

            $apiContext,

            $restCall

        );

        $ret = new Plan();

        $ret->fromJson($json);

        return $ret;

    }



    /**

     * Create a new billing plan by passing the details for the plan, including the plan name, description, and type, to the request URI.

     *

     * @param ApiContext $apiContext is the APIContext for this call. It can be used to pass dynamic configuration and credentials.

     * @param PayPalRestCall $restCall is the Rest Call Service that is used to make rest calls

     * @return Plan

     */

    public function create($apiContext = null, $restCall = null)

    {

        $payLoad = $this->toJSON();

        $json = self::executeCall(

            "/v1/payments/billing-plans/",

            "POST",

            $payLoad,

            null,

            $apiContext,

            $restCall

        );

        $this->fromJson($json);

        return $this;

    }



    /**

     * Replace specific fields within a billing plan by passing the ID of the billing plan to the request URI. In addition, pass a patch object in the request JSON that specifies the operation to perform, field to update, and new value for each update.

     *

     * @param PatchRequest $patchRequest

     * @param ApiContext $apiContext is the APIContext for this call. It can be used to pass dynamic configuration and credentials.

     * @param PayPalRestCall $restCall is the Rest Call Service that is used to make rest calls

     * @return bool

     */

    public function update($patchRequest, $apiContext = null, $restCall = null)

    {

        ArgumentValidator::validate($this->getId(), "Id");

        ArgumentValidator::validate($patchRequest, 'patchRequest');

        $payLoad = $patchRequest->toJSON();

        self::executeCall(

            "/v1/payments/billing-plans/{$this->getId()}",

            "PATCH",

            $payLoad,

            null,

            $apiContext,

            $restCall

        );

        return true;

    }



    /**

     * Delete a billing plan by passing the ID of the billing plan to the request URI.

     *

     * @param ApiContext $apiContext is the APIContext for this call. It can be used to pass dynamic configuration and credentials.

     * @param PayPalRestCall $restCall is the Rest Call Service that is used to make rest calls

     * @return bool

     */

    public function delete($apiContext = null, $restCall = null)

    {

        ArgumentValidator::validate($this->getId(), "Id");

        $patchRequest = new PatchRequest();

        $patch = new Patch();

        $value = new PayPalModel('{

            "state":"DELETED"

        }');

        $patch->setOp('replace')

            ->setPath('/')

            ->setValue($value);

        $patchRequest->addPatch($patch);

        return $this->update($patchRequest, $apiContext, $restCall);

    }



    /**

     * List billing plans according to optional query string parameters specified.

     *

     * @param array $params

     * @param ApiContext $apiContext is the APIContext for this call. It can be used to pass dynamic configuration and credentials.

     * @param PayPalRestCall $restCall is the Rest Call Service that is used to make rest calls

     * @return PlanList

     */

    public static function all($params, $apiContext = null, $restCall = null)

    {

        ArgumentValidator::validate($params, 'params');

        $payLoad = "";

        $allowedParams = array(

            'page_size' => 1,

            'status' => 1,

            'page' => 1,

            'total_required' => 1

        );

        $json = self::executeCall(

            "/v1/payments/billing-plans/" . "?" . http_build_query(array_intersect_key($params, $allowedParams)),

            "GET",

            $payLoad,

            null,

            $apiContext,

            $restCall

        );

        $ret = new PlanList();

        $ret->fromJson($json);

        return $ret;

    }



}

