%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /var/www/html/bbw/farmaci/kritik-portale/module/ReviewBase/src/ReviewBase/Model/
Upload File :
Create Path :
Current File : /var/www/html/bbw/farmaci/kritik-portale/module/ReviewBase/src/ReviewBase/Model/FastbillAPI.php

<?php

/**
 * Description of Fastbill
 *
 * @author Rene Winkler ( conlabz GmbH ) <rene.winkler@conlabz.de>
 * 
 */

namespace ReviewBase\Model;

use DateTime;
use FastBill\FastBill;
use ReviewBase\DB\TableGateway\Feature\BillingActiveFeature;
use ReviewBase\DB\TableGateway\Feature\BillingAsyncFeature;
use ReviewBase\DB\TableGateway\Feature\BillingCanceledFeature;
use ReviewBase\DB\TableGateway\Feature\BillingConnectedFeature;
use ReviewBase\DB\TableGateway\Feature\BillingDeployFeature;
use ReviewBase\DB\TableGateway\Feature\BillingDisconnectedFeature;
use ReviewBase\DB\TableGateway\Feature\BillingInactiveFeature;
use ReviewBase\Entity\ContractEntity;
use ReviewPharmacy\Model\CronJobUtility;

//require_once("./vendor/digitalschmiede/fastbill/src/FastBill/FastBill.php");

class FastbillAPI
{
    /**
     * @var \FastBill\FastBill $fastbill
     */
    protected $fastbill;
    
    protected $contractFactory;
    
    protected $pharmacyFactory;

    protected $fastbill_config;
    
    protected $cronjobUtility;
    
    public function __construct($config,
                                $debug = false,
                                $contractFactory,
                                $pharmacyFactory,
                                CronJobUtility $cronjobUtility)
    {
        $this->fastbill_config = $config['api_credentials'][$config["fastbillAccount"]];
        $this->fastbill = new \FastBill\FastBill($this->fastbill_config['email'], $this->fastbill_config['apiKey'], $this->fastbill_config['apiUrl']);
        $this->contractFactory = $contractFactory;
        $this->pharmacyFactory = $pharmacyFactory;
        $this->cronjobUtility = $cronjobUtility;
        
        //@todo handle if fastbill API is not reachable
        //@todo decide what is better: at a per request basis or on a object basis
        //http://thisinterestsme.com/php-error-handling-curl/
        //http://thisinterestsme.com/check-see-http-resource-exists-php/
        $this->fastbill->setDebug($debug);
    }

    /**
     * @param array $request
     * @return array|bool
     */
    public function requestAPI(array $request)
    {
        $answer = $this->fastbill->request($request);
        if (is_array($answer))
        {
            //only return array if there is an actual response
            $answer = array_key_exists("RESPONSE", $answer) ? $answer : false;
        }
        return $answer;
    }

    /**
     * @return bool
     */
    public function checkAPICredentials()
    {
        return $this->fastbill->checkAPICredentials();
    }

    /**
     * @param bool|false  $debug
     */
    public function setDebug($debug = false)
    {
        $this->fastbill->setDebug($debug);
    }

    /**
     * @param bool|false $convert
     */
    public function setConvertToUTF8($convert = false)
    {
        $this->fastbill->setConvertToUTF8($convert);
    }
    
    /**
     * Extensions for convenience and repetitive tasks
     */
    
    public function getSubscription($subscriptionHash)
    {
        $subscription = false;
        $requestFastbill = ["SERVICE" => "subscription.get", "FILTER" => ["HASH" => $subscriptionHash]];
        $answerFastbill = $this->requestAPI($requestFastbill);
        if ($answerFastbill && array_key_exists("SUBSCRIPTIONS", $answerFastbill["RESPONSE"]) && (count($answerFastbill["RESPONSE"]["SUBSCRIPTIONS"]) === 1))
        {
            $subscription = $answerFastbill["RESPONSE"]["SUBSCRIPTIONS"][0];
        }
        return $subscription;
    }
    
    public function getCustomer($customerID)
    {
        $customer = false;
        $requestFastbill = ["SERVICE" => "customer.get", "FILTER" => ["CUSTOMER_ID" => $customerID]];
        $answerFastbill = $this->requestAPI($requestFastbill);
        if ($answerFastbill && array_key_exists("CUSTOMERS", $answerFastbill["RESPONSE"]) && (count($answerFastbill["RESPONSE"]["CUSTOMERS"]) === 1))
        {
            $customer = $answerFastbill["RESPONSE"]["CUSTOMERS"][0];
        }
        return $customer;
    }
    
    public function convertSubscriptionStatus($status)
    {
        $internalStatus = null;
        switch($status)
        {
            case("active"):$internalStatus = BillingActiveFeature::STATUS_ACTIVE; break;
            case("inactive"):$internalStatus = BillingInactiveFeature::STATUS_INACTIVE; break;
            case("canceled"):$internalStatus = BillingCanceledFeature::STATUS_CANCELED; break;
            default:break;
        }
        return $internalStatus;
    }
    
    public function getCoupon($couponCode)
    {
        $coupon = false;
        $requestFastbill = ["SERVICE" => "coupon.get", "FILTER" => ["CODE" => $couponCode]];
        $answerFastbill = $this->requestAPI($requestFastbill);
        if ($answerFastbill && !$this->errorExists($answerFastbill))
        {
            $countCoupons = count($answerFastbill["RESPONSE"]["COUPONS"]);
            if ($countCoupons === 1)
            {
                $coupon = $answerFastbill["RESPONSE"]["COUPONS"][0];
            }
        }
//        var_dump($coupon);
        return $coupon;
    }
    
    public function getSubscriptionID($subscriptionHash)
    {
        $subscriptionID = null;
        $subscription = $this->getSubscription($subscriptionHash);
        if ($subscription)
        {
            $subscriptionID = $subscription["SUBSCRIPTION_ID"];
        }
        return $subscriptionID;
    }
    
    public function validateCustomerHash($customerID, $customerHash)
    {
        $valid = false;
        $customer = $this->getCustomer($customerID);
        if ($customer)
        {
            var_dump($customer);
            $customerHashFromFastbill = $customer["HASH"];
            $valid = ($customerHash === $customerHashFromFastbill) ? true : false;
        }
        return $valid;
    }
    
    public function getSecureLinksSubscription($subscriptionID)
    {
//        $secureLinks = [];
        $secureLinks["ADDONS_URL"] = null;
        $secureLinks["CANCEL_URL"] = null;
        $secureLinks["REACTIVATE_URL"] = null;
        $requestFastbill = ["SERVICE" => "subscription.createsecurelink", "DATA" => ["SUBSCRIPTION_ID" => $subscriptionID]];
        $answerFastbill = $this->requestAPI($requestFastbill);
        if ($answerFastbill && !$this->errorExists($answerFastbill))
        {
            $secureLinks["ADDONS_URL"] = $answerFastbill["RESPONSE"]["ADDONS_URL"];
            $secureLinks["CANCEL_URL"] = $answerFastbill["RESPONSE"]["CANCEL_URL"];
            $secureLinks["REACTIVATE_URL"] = $answerFastbill["RESPONSE"]["REACTIVATE_URL"];
        }
        return $secureLinks;
    }
    
    public function getSecureLinksCustomer($customerID)
    {
//        $secureLinks = [];
        $secureLinks["ACCOUNTDATA_URL"] = null;
        $secureLinks["DASHBOARD_URL"] = null;
        $requestFastbill = ["SERVICE" => "customer.createsecurelink", "DATA" => ["CUSTOMER_ID" => $customerID]];
        $answerFastbill = $this->requestAPI($requestFastbill);
        if ($answerFastbill && !$this->errorExists($answerFastbill))
        {
            $secureLinks["ACCOUNTDATA_URL"] = $answerFastbill["RESPONSE"]["ACCOUNTDATA_URL"];
            $secureLinks["DASHBOARD_URL"] = $answerFastbill["RESPONSE"]["DASHBOARD_URL"];
        }
        return $secureLinks;
    }
    
    protected function getErrors($answerFastbill)
    {
        $errors = [];
        if ($this->errorExists($answerFastbill))
        {
            if (array_key_exists("ERRORS", $answerFastbill["RESPONSE"]))
            {
                $errors = $answerFastbill["RESPONSE"]["ERRORS"];
            }
            //grab those coming from FastBill-PHP API Implementation
            if (array_key_exists("ERROR", $answerFastbill["RESPONSE"]))
            {
                foreach($answerFastbill["RESPONSE"]["ERROR"] as $error)
                {
                    array_push($errors, $error);
                }
            }
        }
        return $errors;
    }
    
    protected function errorExists($answerFastbill)
    {
        $errorExists = false;
//        if (isset($answerFastbill["RESPONSE"]["ERRORS"]))
        if (!empty($answerFastbill["RESPONSE"])
            && (array_key_exists("ERRORS", $answerFastbill["RESPONSE"]) 
                || array_key_exists("ERROR", $answerFastbill["RESPONSE"])))
        {
            $errorExists = true;
        }
        return $errorExists;
    }
    
    public function getPriceForSubscription($subscription)
    {
        $price = null;
        if($subscription)
        {
            $price = $subscription["PLAN"]["UNIT_PRICE"];
            $couponCode = array_key_exists("COUPON", $subscription) ? $subscription["COUPON"]["CODE"] : false;
            //only make an api call if the object id is missing
            if ($couponCode)
            {
                $coupon = $this->getCoupon($couponCode);
                $price = $price - $coupon["DISCOUNT_AMOUNT"];
            }
        }
        return $price;
    }
        
    public function getSubscriptionCancellationDate($subscriptionHash)
    {
        $cancellation_date = null;
        $subscription = $this->getSubscription($subscriptionHash);
        if (count($subscription) !== 0)
        {
            $cancellation_date = $subscription["CANCELLATION_DATE"];
        }
        return $cancellation_date;
    }
    
    /**
     * 
     * @param type $status possible values are "active", "inactive", "canceled"
     * @param type $subscriptionHash
     * @return boolean true on successfull status change
     */
    public function setStatus($status, $subscriptionHash)
    {
        $success = false;
        $subscriptionID = $this->getSubscriptionID($subscriptionHash);
        $requestFastbill = ["SERVICE" => "subscription.update", "DATA" => ["SUBSCRIPTION_ID" => $subscriptionID, "STATUS" => $status]];
        $answerFastbill = $this->requestAPI($requestFastbill);
        if ($answerFastbill && !$this->errorExists($answerFastbill))
        {
            $success = true;
        }
        return $success;
    }
    
    public function getObjectIDForSubscription ($subscriptionHash)
    {
        $objectID = false;
        $subscription = $this->getSubscription($subscriptionHash);
//        var_dump($subscription["X_ATTRIBUTES"]);
        foreach ($subscription["X_ATTRIBUTES"] as $key=>$value)
        {
            if ($value["KEY"] === "objectID")
            {
                $objectID = $value["VALUE"];
                break;
            }
        }
        return $objectID;
    }
    
    public function determineContractStatus($contract, $pharmacy)
    {
        $contractStatus = false;
        if ($pharmacy->plan_version === $contract->plan_version)
        {
            $contractStatus = BillingConnectedFeature::STATUS_CONNECTED;
        }
        else
        {
            $contractStatus = BillingDisconnectedFeature::STATUS_DISCONNECTED;
        }
        return $contractStatus;
    }
    
    public function syncSubscription(ContractEntity $contract)
    {
        $subscription = $this->getSubscription($contract->external_subscription_hash);
        $nowDateTime = new DateTime();
        $now = $nowDateTime->format(UtilityDate::getDefaultStorageFormat());
        //check if there is a subscription in fastbill
        if ($subscription)
        {
            $customer_number = $subscription["CUSTOMER_ID"];
            $subscription_id = $subscription["SUBSCRIPTION_ID"];
            $startDate = $subscription["START"];
            $cancellationDate = $subscription["CANCELLATION_DATE"];
            $expirationDate = $subscription["EXPIRATION_DATE"];
            $external_status = $this->convertSubscriptionStatus($subscription["STATUS"]);
            //calculate netto price
            $planPrice = $subscription["PLAN"]["UNIT_PRICE"];
            $couponCode = array_key_exists("COUPON", $subscription) ? $subscription["COUPON"]["CODE"] : false;
            //only make an api call if there is a coupon code on this subscription
            if ($couponCode)
            {
                $coupon = $this->getCoupon($couponCode);
                $planPrice = $planPrice - $coupon["DISCOUNT_AMOUNT"];
            }
            $contractObject = $this->contractFactory->getContract($contract->entityid);
            /**
             *  check if objectID is missing in contract and try to retrieve it
             *  from fastbill
             */
            $contractObjectID = $contractObject->getObjectID();
            //only make an api call if the object id is missing
            if (empty($contractObjectID))
            {
                $subscriptionObjectID = $this->getObjectIDForSubscription($contractObject->getExternalSubscriptionHash());
                if($subscriptionObjectID)
                {
                    $contractObject->setObjectID($subscriptionObjectID);
                }
            }
            $contractObject->setCustomerNumber($customer_number);
            $contractObject->setContractNumber($subscription_id);
            $contractObject->setPlanPrice($planPrice);

            $planEnd = null;
            $currentContractPlanEnd = $contractObject->getPlanEnd();
            $currentEndDate = new DateTime($currentContractPlanEnd);
            if (($external_status === BillingActiveFeature::STATUS_ACTIVE) && ($cancellationDate === "0000-00-00 00:00:00"))
            {
                $planEnd = $expirationDate;
            }
            elseif(($external_status === BillingActiveFeature::STATUS_ACTIVE) || ($external_status === BillingCanceledFeature::STATUS_CANCELED))
            {
                $planEnd = $cancellationDate;
            }
            elseif(($external_status === BillingInactiveFeature::STATUS_INACTIVE) && ($currentEndDate > $nowDateTime))
            {
                //if subscription is inactive, set end date to today while
                //preventing a per cronjob update of the field if endtime
                //was in the past
                $planEnd = $now;
            }

            $contractObject->setPlanStart($startDate);
            if (!empty($planEnd))
            {
                $contractObject->setPlanEnd($planEnd);
            }

            $contractObject->setExternalStatus($external_status);
            
            $eventCount = count($contractObject->getEvents());
//            var_dump($contractObject);
//            var_dump($subscription);
            //retrieve current status for contract
//            $pharmacy = $this->pharmacyFactory->showRateableObject($contract->objectid);
            $pharmacy = $this->pharmacyFactory->getRateableObject($contract->objectid, true);
            $status = $this->determineContractStatus($contract, $pharmacy);
            
            //if contract has changed in any way - add deploy task
            if ($eventCount > 0)
            {
//                echo PHP_EOL."Contract Changed".PHP_EOL;
//                $status = BillingDeployFeature::STATUS_DEPLOY;
                $this->cronjobUtility->addCronTask($contractObject->getId(), "contract", BillingDeployFeature::STATUS_DEPLOY, "hourly");
                $modified = new DateTime();
                $contractObject->setModified($modified->format(UtilityDate::getDefaultStorageFormat()));
            }
            
            $contractObject->setStatus($status);
            $this->contractFactory->save($contractObject);
        }
        elseif(!$subscription)
        {
            /**
             * mark contract as async since no subscription could be obtained from fastbill
             */
            $contractObject = $this->contractFactory->getContract($contract->entityid);
            $contractObject->setStatus(BillingAsyncFeature::STATUS_ASYNC);

            $this->contractFactory->save($contractObject);
        }
    }

}

Zerion Mini Shell 1.0