%PDF- %PDF-
Mini Shell

Mini Shell

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

<?php
/**
 * Created by PhpStorm.
 * User: juliangilles
 * Date: 09.09.15
 * Time: 14:53
 */

namespace ReviewPharmacy\Model;

use Basis\EventStore\EventStore;
use Basis\Model\User\UserFactory;
use DateInterval;
use DateTime;
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\DB\TableGateway\Feature\BillingSyncFeature;
use ReviewBase\Model\ClaimActivationFactory;
use ReviewBase\Model\CleverReachManager;
use ReviewBase\Model\ContractFactory;
use ReviewBase\Model\UtilityDate;
use RuntimeException;
use Zend\Console\Request;
use Zend\Db\TableGateway\TableGateway;
use Zend\ServiceManager\ServiceManager;

class CronJob
{
    /**
     * @var ServiceLocatorInterface
     */
    protected $serviceLocator;
    
    protected $viewsDBAdapter;
    
    protected $systemDBAdapter;

    /**
     * @var PharmacyFactory
     */
    protected $pharmacyFactory;

    /**
     * @var ContractFactory
     */
    protected $contractFactory;

    /**
     * @var ClaimActivationFactory
     */
    protected $claimActivationFactory;

    /**
     * @var UserFactory
     */
    protected $userFactory;
    
    protected $fastbillAPI;

    protected $cleverReachManager;
    
    protected $cronjobUtility;
    
    /**
     * @var array
     */
    protected $reviewConfig;

    public function __construct(ServiceManager $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
        $serviceManager = $serviceLocator;
//        $authorizationService = $serviceManager->get('ZfcRbac\Service\AuthorizationService');

        $this->systemDBAdapter = $serviceManager->get('systemDB');
        $this->viewsDBAdapter = $serviceManager->get('viewsDB');

        $eventBus = $serviceManager->get('eventBus');
//        $databaseAdapter = $serviceManager->get('systemDB');
//        $searchDBAdapter = $serviceManager->get('viewsDB');
        $config = $serviceManager->get('config');
        
        $this->cronjobUtility = new CronJobUtility($serviceLocator);
        $this->cleverReachManager = $serviceManager->get('ReviewBase\Model\CleverReachManager');
        $this->pharmacyFactory = $serviceManager->get('ReviewPharmacy\Model\PharmacyFactory');
//        $this->tmp_reviewRepository = $serviceManager->get('ReviewPharmacy\Repository\ReviewPharmacyRepository');
        $this->claimActivationFactory = new ClaimActivationFactory($eventBus, $this->systemDBAdapter, $this->viewsDBAdapter);
        $this->contractFactory = new ContractFactory($eventBus, $this->systemDBAdapter, $this->viewsDBAdapter);
        $this->userFactory = new UserFactory($serviceManager, $eventBus);
        $this->reviewConfig = $config['review'];
        
        $this->fastbillAPI = $serviceManager->get('ReviewBase\Model\FastbillAPI');

    }

    /**
     * @param Request $request
     */
    public function run(Request $request)
    {
        switch ($request->getParam('command')) {
            case "cronjob":
                $this->cronjob($request);
                break;
            case "claimremind":
                $this->claimremind($request);
                break;
            case "calcaveragerating":
                $this->calcaveragerating($request);
                break;
            case "updateplan":
                $this->updatePlan($request);
                break;
            case "syncfastbill":
                $this->syncFastbill($request);
                break;
            case "daily":
                $this->updateSitemap();
                $this->syncFastbillAll($request);
                break;
            case "importcleverreach":
                $this->importCleverReach();
                break;
//            case "testcleverreach":
//                $this->testCleverReach();
//                break;
            default:
                throw new RuntimeException("parameter not found!");
        }
    }

    protected function importCleverReach() {
        echo "importCleverReach --- " . PHP_EOL;
        echo "mainListID: " . $this->cleverReachManager->getListID().PHP_EOL;
        echo "criticizedListID: " . $this->cleverReachManager->getCriticizedListID().PHP_EOL;
        $this->cleverReachManager->groupCSVImport();
    }

//    protected function testCleverReach() {
//        $review = $this->pharmacyFactory->getReview('5602a0418ce7f');
//        $review->setReviewApprovedMail($this->pharmacyFactory->getRateableObject($review->getObjectID()));
//        $this->tmp_reviewRepository->save($review);
//
//        $review = $this->pharmacyFactory->getReview('5629f0f757561');
//        $review->setReviewApprovedMail($this->pharmacyFactory->getRateableObject($review->getObjectID()));
//        $this->tmp_reviewRepository->save($review);
//
//        $review = $this->pharmacyFactory->getReview('563a019dde665');
//        $review->setReviewApprovedMail($this->pharmacyFactory->getRateableObject($review->getObjectID()));
//        $this->tmp_reviewRepository->save($review);
//
//        $review = $this->pharmacyFactory->getReview('564f453a34a47');
//        $review->setReviewApprovedMail($this->pharmacyFactory->getRateableObject($review->getObjectID()));
//        $this->tmp_reviewRepository->save($review);

//        $this->updateCleverReach();
//    }

    protected function updateCleverReach()
    {
        $tasks = $this->cronjobUtility->getAllTasksFor('cleverreach');
        foreach ($tasks as $task)
        {
            //echo 'Task -- type:' . $task['type'] . ' interval: ' . $task['interval'].PHP_EOL;

            $taskID = $task['id'];

            //load review
            $review = $this->pharmacyFactory->showReview($task['entityid']);
            if($review)
            {
                $isEmailOfPharmacy = false;
                $isEmailOfUser = false;
                $firstname = '';
                $lastname = '';
                $userEmail = '';
                $email = '';

                $pharmacyID = $review->objectid;
                $last_email_send = $review->comment_review_date;
                $pharmacy = $this->pharmacyFactory->getRateableObject($pharmacyID, true);
                $pharmacyEmail = $pharmacy->getEmail();
                $ownerID = $pharmacy->getOwner();
                $user = $this->userFactory->showUser($ownerID);
                if ($user) {
                    $userEmail = $user->email;
                }

                if (!empty($userEmail))
                {
                    $isEmailOfUser = true;
                    $email = $userEmail;
                    $firstname = $user->name;
                    $lastname = $user->surname;
                }
                else if(!empty($pharmacyEmail))
                {
                    $email = $pharmacyEmail;
                    $isEmailOfPharmacy = true;
                }
                if ($pharmacyEmail === $userEmail)
                {
                    $isEmailOfPharmacy = true;
                    $isEmailOfUser = true;
                }

                if(!empty($email)) {
                    $success = $this->cleverReachManager->updateReceiverOnCriticizedList(
                        $email,
                        $last_email_send,
                        $isEmailOfPharmacy,
                        $isEmailOfUser,
                        $firstname,
                        $lastname
                    );
                    if ($success) {
                        //we did the work, remove task
                        $this->cronjobUtility->removeCronTask($taskID);
                    }
                }
                else {
                    //no email exists so we cannot update the list on cleverreach, remove task
                    $this->cronjobUtility->removeCronTask($taskID);
                }
            }
            else {
                //review does not exist any longer, remove task
                $this->cronjobUtility->removeCronTask($taskID);
            }
        }
    }
    
    private function hourly(Request $request)
    {
        $success = false;
        $this->calcaveragerating($request);
        $this->syncFastbill($request);
        $this->updatePlan($request);
        $this->updateCleverReach();
        $success = true;
        return $success;
    }
    
    private function daily(Request $request)
    {
        $success = false;
        $this->claimremind($request);
        $this->updateSitemap();
        $this->syncFastbillAll($request);
        $success = true;
        return $success;
    }
    
    private function weekly(Request $request)
    {
        return true;
    }

    private function cronjob(Request $request)
    {
//        echo "cronjob()".PHP_EOL;
        $nextRun = $this->cronjobUtility->nextRun();
//        var_dump($nextRun);
        $returnHourly = false;
        $returnDaily = false;
        $returnWeekly = false;
        foreach ($nextRun as $interval => $value)
        {
            $return = "return". ucfirst($interval);
            if ($value)
            {
                try
                {
                    $$return = $this->$interval($request);
                }
                catch (Exception $exc)
                {
                    $$return = false;
                }
            }
        }

        //only save run time for interval-job if successfully returned
        $saveRunTime = [
            "hourly" => $returnHourly,
            "daily" => $returnDaily,
            "weekly" => $returnWeekly
        ];
//        var_dump($saveRunTime);
        $this->cronjobUtility->saveRunTime($saveRunTime);
    }
    
    /**
     * @param Request $request
     */
    private function updatePlan(Request $request)
    {
        //update those contracts which are marked for deploy
        $this->deployPharmacies($request);
        
        /**
         * Update those plans which are ready to start
         */
        $contracts = $this->contractFactory->getContractsForPlanUpdate();
        foreach ($contracts as $contract) {
//            var_dump($contract);
//            $pharmacy = $this->pharmacyFactory->showRateableObject($contract->objectid);
            $pharmacy = $this->pharmacyFactory->getRateableObject($contract->objectid, true);
            if ($pharmacy->plan_version !== $contract->plan_version) {
                $pharmacy = $this->pharmacyFactory->getRateableObject($contract->objectid);
                $pharmacy->setPlanName($contract->plan_name);
                $pharmacy->setPlanVersion($contract->plan_version);
                $this->pharmacyFactory->consoleSaveRateableObject($pharmacy, $request);
                
                $contractObject = $this->contractFactory->getContract($contract->entityid);
                $contractObject->setStatus(BillingConnectedFeature::STATUS_CONNECTED);
                $this->contractFactory->save($contractObject);
            }
        }
        
        //disconnect those contracts which are over
        $this->demotePlan($request, "basis", "BasisPlanV1");
    }
    
    private function demotePlan(Request $request, $plan_name, $plan_version)
    {
        $contractsForDowngrade = $this->contractFactory->getContractsForPlanDowngrade();
        foreach ($contractsForDowngrade as $contract)
        {
//            var_dump($contract);
//            $pharmacy = $this->pharmacyFactory->showRateableObject($contract->objectid);
            $pharmacy = $this->pharmacyFactory->getRateableObject($contract->objectid, true);
            if ($pharmacy->plan_version !== $plan_version) {
                $pharmacy = $this->pharmacyFactory->getRateableObject($contract->objectid);
                $pharmacy->setPlanName($plan_name);
                $pharmacy->setPlanVersion($plan_version);
                $this->pharmacyFactory->consoleSaveRateableObject($pharmacy, $request);
                
                $contractObject = $this->contractFactory->getContract($contract->entityid);
                $contractObject->setStatus(BillingDisconnectedFeature::STATUS_DISCONNECTED);
                $this->contractFactory->save($contractObject);
            }
        }
    }
    
    private function deployPharmacies(Request $request)
    {
//        $contracts = $this->contractFactory->getContractsForDeploy();
        $contracts = $this->contractFactory->getTaskContracts(BillingDeployFeature::STATUS_DEPLOY, "hourly");
        
        foreach ($contracts as $contract)
        {
//            $pharmacy = $this->pharmacyFactory->showRateableObject($contract->objectid);
            $pharmacy = $this->pharmacyFactory->getRateableObject($contract->objectid, true);
            
            //decide if to upgrade or downgrade pharmacy
            $connect = $this->decideForConnection($contract, $pharmacy);
            $pharmacyObject = $this->pharmacyFactory->getRateableObject($contract->objectid);
            $contractStatus = null;
            if ($connect)
            {
                $pharmacyObject->setPlanName($contract->plan_name);
                $pharmacyObject->setPlanVersion($contract->plan_version);
                $contractStatus = BillingConnectedFeature::STATUS_CONNECTED;
            }
            else
            {
                //set to base plan
                $pharmacyObject->setBasePlan();
                $contractStatus = BillingDisconnectedFeature::STATUS_DISCONNECTED;
            }
            $this->pharmacyFactory->consoleSaveRateableObject($pharmacyObject, $request);

            //set status for contract
            $contractObject = $this->contractFactory->getContract($contract->entityid);
            $contractObject->setStatus($contractStatus);
            $this->contractFactory->save($contractObject);
            
            $this->cronjobUtility->removeCronTask($contract->cron_task_id);
        }
    }
    
    private function decideForConnection($contract, $pharmacy)
    {
        $connect = false;
        $nowDateTime = new DateTime();
        $now = $nowDateTime->format(UtilityDate::getDefaultStorageFormat());
        $currentContractPlanEnd = $contract->plan_end;
        $currentEndDate = new DateTime($currentContractPlanEnd);
        if (($contract->external_status === BillingActiveFeature::STATUS_ACTIVE)
            && ($currentEndDate > $nowDateTime))
        {
            $connect = true;
        }
        return $connect;
    }
    
    /**
     * Do not overuse fastbill API-Calls here, only 1000 per user and minute are allowed
     * @param Request $request
     */
    private function syncFastbill(Request $request)
    {
//        $contracts = $this->contractFactory->getContractsForSync();
        $contracts = $this->contractFactory->getTaskContracts(BillingSyncFeature::STATUS_SYNC, "hourly");
        $this->syncContracts($request, $contracts);
    }
    
    /**
     * Do not overuse fastbill API-Calls here, only 1000 per user and minute are allowed
     * @param Request $request
     */
    private function syncFastbillAll(Request $request)
    {
        /**
         * make sure only to add new tasks for all contracts if the old "stack"
         * was processed
         */
        $oldTaskContracts = $this->contractFactory->getTaskContracts(BillingSyncFeature::STATUS_SYNC, "daily");
        $hasTasks = (count($oldTaskContracts) > 0) ? true : false;
        if (!$hasTasks)
        {
            $this->addTasksForAllContracts();
        }
        $contracts = $this->contractFactory->getTaskContracts(BillingSyncFeature::STATUS_SYNC, "daily");
        $this->syncContracts($request, $contracts);
    }
    
    private function addTasksForAllContracts()
    {
        $contracts = $this->contractFactory->getContracts();
        foreach($contracts as $contract)
        {
            $this->cronjobUtility->addCronTask($contract->entityid, "contract", BillingSyncFeature::STATUS_SYNC, "daily");
        }
    }
    
    private function syncContracts(Request $request, $contracts)
    {      
        foreach ($contracts as $contract)
        {
            $this->fastbillAPI->syncSubscription($contract);
            //remove the task from the task list
            $this->cronjobUtility->removeCronTask($contract->cron_task_id);
        }
    }

    /**
     * @param Request $request
     */
    private function claimremind(Request $request)
    {
//        echo "Claim Reminder-Email" . PHP_EOL;
        //delete all deprecated claims from db
        $this->claimActivationFactory->deleteOldClaims();
        $claimsToRemind = $this->claimActivationFactory->showAllClaimsForRemind();
        foreach ($claimsToRemind as $claim) {
//            echo $claim->entityid . PHP_EOL;
            $now = new DateTime();

            $claimCreatedAt = new DateTime($claim->created_at);
            $timeDifference = $now->diff($claimCreatedAt);
//            echo "Time difference: " . $timeDifference->format('%d D %h H %i M') . PHP_EOL;
            /**
             * if no reminder was send yet, send an email with the information
             */
            if (!$claim->remind) {
                $user = $this->userFactory->getUser($claim->userid);
                $pharmacy = $this->pharmacyFactory->getRateableObject($claim->objectid);
                $this->pharmacyFactory->saveActivationLinkSendEventForPharmacy($claim->objectid, $user, $claim->hash, true);
                $claimObject = $this->claimActivationFactory->getClaimActivation($claim->entityid);
                $claimObject->setRemind(1);
                $this->claimActivationFactory->save($claimObject);
//                echo "Reminder email send" . PHP_EOL;
            }
        }
    }

    /**
     * @param Request $request
     */
    private function calcaveragerating(Request $request)
    {
        $period = date("Y-m-d H:i:s", strtotime('-' . $this->reviewConfig['period']));
        $now = new DateTime();
        $eventStore = new EventStore();
        $eventStore->setDatabaseAdapter($this->systemDBAdapter);

        // get last ReviewAverageCalculationStart
        $lastStart = $eventStore->getLastEventOfType('ReviewBase\Event\AbstractReview\ReviewAverageCalculationStart');
        $eventsToSearch = [
            'ReviewBase\Event\AbstractReview\ReviewChangedRatings',
            'ReviewBase\Event\AbstractReview\ReviewChangedLastModified',
            'ReviewBase\Event\AbstractReview\ReviewChangedCommentStatus',
            'ReviewBase\Event\AbstractReview\ReviewDeleted'
        ];

        //if last start  === null calc all
        if (is_null($lastStart)) {
            //    foreach pharmacy
            //    calc average from period begin to start
            $events = $eventStore->loadEventsByType('ReviewBase\Event\AbstractReview\ReviewChangedRatings', true);
            if (!empty($events)) {
                $objectIDs = [];

                foreach ($events as $entityid)
                {                   
                    $objectEventArray = $eventStore->loadEventsByType('ReviewBase\Event\AbstractReview\ReviewChangedObjectID', false, $entityid);
                    $objectEvent = $objectEventArray[0];
                    $params = $objectEvent->getParams(false);
                    $objectIDs[$params->objectid] = $params->objectid;
                }
                //  create new ReviewAverageCalculationStart
                $this->pharmacyFactory->startAverageCalculation();
                $this->pharmacyFactory->calcAverageRating(array_keys($objectIDs), $period, $now->format("Y-m-d H:i:s"));
                //  create new ReviewAverageCalculationEnd
                $this->pharmacyFactory->endAverageCalculation();
            }

        } else {
            // get pharmacies with new or expired reviews

            $lastStartTimeObject = new DateTime($lastStart->time);
            $periodIntervalEnd = new DateTime($period);
            $periodIntervalEnd->sub($now->diff($lastStartTimeObject));
            
            $events = $eventStore->loadEventsByTwoIntervals($eventsToSearch, $lastStart->time, $now->format("Y-m-d H:i:s"), $periodIntervalEnd->format("Y-m-d H:i:s"), $period, true);
            //    foreach pharmacy calc average from start to period begin
            if (!empty($events)) {
                $objectIDs = [];
                //  create new ReviewAverageCalculationStart
                $this->pharmacyFactory->startAverageCalculation();
                foreach ($events as $entityid)
                {
                    /** @var \ReviewBase\Event\AbstractReview\ReviewChangedObjectID $objectEvent */
                    $objectEventArray = $eventStore->loadEventsByType('ReviewBase\Event\AbstractReview\ReviewChangedObjectID', false, $entityid);
                    $objectEvent = $objectEventArray[0];
                    $params = $objectEvent->getParams(false);
                    $objectIDs[$params->objectid] = $params->objectid;
//                    var_dump($params->objectid);
                    
                }
                $this->pharmacyFactory->calcAverageRating(array_keys($objectIDs), $period, $now->format("Y-m-d H:i:s"));
                //  create new ReviewAverageCalculationEnd
                $this->pharmacyFactory->endAverageCalculation();
            }
        }
    }

    private function updateSitemap()
    {
        /** @var $siteMapGenerator \ReviewPharmacy\Model\SitemapGenerator */
        $siteMapGenerator = $this->serviceLocator->get("ReviewPharmacy\Model\SitemapGenerator");
        $letters = range('A', 'Z');
        foreach ($letters as $letter) {
            $siteMapGenerator->generateSitemap($letter);
        }
    }
}

Zerion Mini Shell 1.0