InboundCallManager.php 6.06 KB
<?php


namespace NexmoBundle\Manager;

use AppBundle\Entity\AdminUser;
use AppBundle\Entity\OpentokSessionTypes;
use AppBundle\Entity\Patient;
use AppBundle\Entity\ThreadContent;
use AppBundle\Entity\VoiceCall;
use AppBundle\Exception\NotExistEntityException;
use AppBundle\Service\Manager\ContactNumberManager;
use AppBundle\Service\Manager\PatientManager;
use AppBundle\Service\Manager\ThreadNoteManager;
use AppBundle\Service\ThreadContentFactory;
use JMS\DiExtraBundle\Annotation\Inject;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\DiExtraBundle\Annotation\Service;
use NexmoBundle\VoiceCall\VoiceCallOrigins;
use OpenTokBundle\Pool\GlobalAdminOpenTokPool;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

/**
 * Class InboundCallManager
 * @Service("nexmo.manager.inbound_call", parent="nexmo.base_manager", autowire=true, public=true)
 */
class InboundCallManager extends NexmoCallManager
{
    /**
     * @var ThreadContentFactory
     */
    private $threadContentFactory;

    /**
     * @var PatientManager
     */
    private $patientManager;

    /**
     * @var ThreadNoteManager
     */
    private $threadNoteManager;

    /**
     * @var ContactNumberManager
     */
    private $contactNumberManager;

    /**
     * Setter Injector for PatientManager
     * @param $patientManager
     * @InjectParams({
     *     "patientManager" = @Inject("spoke.manager.patient", required=false)
     * })
     */
    public function setPatientManager(PatientManager $patientManager)
    {
        $this->patientManager = $patientManager;
    }

    /**
     * Setter Injector for ThreadContentFactory
     * @param $threadContentFactory
     * @InjectParams({
     *     "threadContentFactory" = @Inject("app.service.thread_content_factory", required=true)
     * })
     */
    public function setThreadContentFactory(ThreadContentFactory $threadContentFactory)
    {
        $this->threadContentFactory = $threadContentFactory;
    }

    /**
     * Setter injector for ThreadNoteManager
     * @param ThreadNoteManager $manager
     * @InjectParams({
     *     "manager" = @Inject("spoke.manager.thread_note", required=true)
     * })
     */
    public function setThreadNoteManager(ThreadNoteManager $manager)
    {
        $this->threadNoteManager = $manager;
    }

    /**
     * Setter injector for ContactNumberManager
     * @param ContactNumberManager $contactNumberManager
     * @InjectParams({
     *     "contactNumberManager" = @Inject("spoke.manager.contactNumber", required=true)
     * })
     */
    public function setContactNumberManager(ContactNumberManager $contactNumberManager)
    {
        $this->contactNumberManager = $contactNumberManager;
    }

    public function create()
    {
        $voiceCall = parent::create();
        $voiceCall->setOriginType(VoiceCallOrigins::MEMBER_USER_INBOUND_CALL);

        return $voiceCall;
    }

    /**
     * Set up thread content for this voice call
     * @param VoiceCall $voiceCall
     * @return null
     * @throws \Exception
     */
    public function initThreadContent(VoiceCall $voiceCall)
    {
        // already created thread content
        if ($voiceCall->getThreadContent()) {
            return null;
        }
        $patient = $voiceCall->getActor();
        if ($patient instanceof Patient) {
            $voiceCall->setThreadContent($this->threadContentFactory->createContent($patient->getThread(), $voiceCall, $patient));
        }
    }

    public function asOpenTokSignalData(VoiceCall $voiceCall)
    {
        $actorData = [
            "number" => $voiceCall->getFromNumber()
        ];
        $patient = $voiceCall->getActor();
        if ($patient instanceof Patient) {
            $actorData = array_merge($actorData, [
                "id" => $patient ? $patient->getId() : 0,
                "name" => $patient->getProfile()->getFullName(),
                "company" => $patient->getCompany()->getName()
            ]);
        }

        $now = new \DateTime('now');
        return [
            "voiceCall" => $voiceCall->getId(),
            "recipient" => $voiceCall->getRecipient() ? $voiceCall->getRecipient()->getId() : null,
            "actor" => $actorData,
            "isCallOngoing" => $voiceCall->getIsCallOngoing(),
            "duration" => $voiceCall->getDuration(),
            "runningDuration" => $now->getTimestamp()-$voiceCall->getCreatedAt()->getTimestamp(),
            "fromNumber" => $voiceCall->getFromNumber()
        ];
    }

    protected function getUpdateMappers(VoiceCall $voiceCall)
    {
        return [
            "actor" => function ($value) use ($voiceCall) {
                $patient = $this->patientManager->getFind($value);

                if (!$patient) {
                    throw new \Exception("Invalid patient actor for voice call.");
                }

                $voiceCallNumber = $voiceCall->getFromNumber();

                $contactNumber = $this->contactNumberManager->create(
                    [
                        'number' => substr($voiceCallNumber, -10),
                        'country_number' => substr($voiceCallNumber, 0, strlen($voiceCallNumber) % 10),
                        'primary' => false
                    ]
                );

                $this->patientManager->update($patient, ['contactNumber' => $contactNumber]);
                $voiceCall->setActor($patient);
                $this->initThreadContent($voiceCall);
            },
            // create ThreadNote for this VoiceCall
            "notes" => function ($value) use ($voiceCall) {
                $parentThreadContent = $voiceCall->getThreadContent();
                $recipient = $voiceCall->getRecipient();

                // must have existing thread content for main voice call log,
                // must have a recipient, automatically set as actor for notes
                if ($parentThreadContent && $recipient) {
                    $threadNote = $this->threadNoteManager->create($value);
                    $this->threadContentFactory->createContent($parentThreadContent->getThread(), $threadNote, $recipient, $parentThreadContent);
                }
            }
        ];
    }
}